有没有办法指定 哪里 T:new() 限制但使用内部构造函数
本文关键字:构造函数 内部 new 哪里 有没有 | 更新日期: 2023-09-27 18:34:02
>我创建了一个需要实例化其实现类型的泛型类,因此实现类型必须具有可访问的参数较少构造函数。看起来 new(( 限制可以完成这项工作,但它强制执行实现类型以在我将其内部拥有公共构造函数时具有公共构造函数(但可访问,因为两者都位于同一程序集上(。
- 有没有理由强制它公开而不是"可访问"?
- 有没有办法做我需要的?
提前谢谢。
编辑:这样做的原因是我有一个必须通过单例使用的X类。Singleton 类是一个泛型类,我想使类 X 构造函数成为内部类,以避免外部用户以错误的方式访问对象(调用构造函数(。
这是 C# 语言不允许的,如规范绑定和未绑定类型的第 4.4.3 节所述。
如果约束是构造函数约束
new()
,则类型A
不得abstract
,并且必须具有公共无参数构造函数。如果满足以下条件之一,则满足此条件。
A
是值类型,因为所有值类型都有一个公共默认构造函数A
是具有余构造函数约束的类型参数A
是具有值类型约束的类型参数A
是一个未abstract
的类,并且包含一个显式声明的不带参数的public
构造器A
不是abstract
,并且具有默认构造函数。
如果不满足这些条件中的任何一个,则为编译器错误。如果您发现自己具有公共类型,但仅具有内部构造函数,那么它们很可能实际上应该是具有公共构造函数的内部类型。
我建议将类型访问器更改为internal
,将其构造函数更改为public
,并使其无参数。然后,public
无参数构造函数可以调用非无参数private
或internal
构造函数来执行任何其他初始化工作。
internal class C<T> where : T new()
{
public C() : this(new T()) {
}
private C(T t) {
// Do additional initialization
}
}
请注意,模式是有限的,但没有什么可以阻止您使用private
方法。
internal class C<T> where T : new() {
public C() {
T t = new T();
InitializeClass(t);
}
private void InitializeClass(T t) {
throw new NotImplementedException();
}
}
根据您的更新,下面是一个公共单例模式的小示例。
public class Singleton<T> where T : new()
{
public static Singleton<T> Current {
get;
private set;
}
internal Singleton() : this(new T()) {
}
private Singleton(T t) {
Current = this;
// Do whatever you need to with T
}
public String Name {
get;
set;
}
}
用法
// Somewhere in your internal assembly
Singleton<String> singleton = new Singleton<String>();
// In an external assembly
Singleton.Current.Name = "SoMoS";
你甚至不需要以这种方式使用构造函数,你可以很容易地做一些简单的事情。
public class Singleton<T> where T : new()
{
public static Singleton<T> Current {
get;
private set;
}
internal Singleton() {
T t = new T();
// Do stuff with T
}
public String Name {
get;
set;
}
}
如果您无法设计泛型以满足您的要求,则可能不是要走的路。泛型只能做这么多,并不能解决所有问题。有工厂模式、注入等。
有没有理由强制它公开而不是"可访问"?
可访问的术语非常上下文相关,泛型不是,按体系结构。在您的特定情况下,可以访问internal
,但泛型是为通用解决方案制作的。
有没有办法做我需要的?
基于第一点,不,这是不可能的,我也不知道。
型用于通用解决方案,因此如果使用"new"约束,则解决方案必须与实现公共ctor的每个类一起使用。
如果要为特定类型的类实现通用解决方案,则可以定义一个实现此类内部构造函数的抽象基类。为此抽象基类实现通用解决方案并使用
*其中 T : MyBaseClassWithInternalCtor*
作为约束。