C#中构造函数的where子句?

C#中构造函数的where子句?,c#,generics,C#,Generics,这就是我要做的 我正在创建一个泛型类,它以两种方式之一分配泛型参数指定的类型,由使用哪个重载构造函数决定 以下是一个例子: class MyClass<T> where T : class { public delegate T Allocator(); public MyClass() { obj = new T(); } public MyClass( Allocator alloc ) {

这就是我要做的

我正在创建一个泛型类,它以两种方式之一分配泛型参数指定的类型,由使用哪个重载构造函数决定

以下是一个例子:

class MyClass<T>
    where T : class
{
    public delegate T Allocator();
    public MyClass()
    {
        obj = new T();
    }

    public MyClass( Allocator alloc )
    {
        obj = alloc();
    }

    T obj;
}
但是,这是无效的C#。基本上,我只想在类型T上添加约束,使其仅在使用MyClass()的默认构造函数时才具有默认构造函数

在MyClass的第二个构造函数中,我们让用户决定如何使用自己的分配方法分配T,因此显然,MyClass不强制T在所有情况下都是默认可构造的

我觉得我需要在默认构造函数中使用反射来实现这一点,但我希望不是这样

我知道这是可以做到的,因为.NET4.0中的
Lazy
类不要求T在类级别是默认可构造的,但它具有与我的示例中类似的构造函数。我想知道懒惰至少是怎么做到的

基本上,我只想在类型T上添加约束,使其仅在使用MyClass()的默认构造函数时才具有默认构造函数

T
上设置约束无法强制执行此操作。您要么在
MyClass
的定义中指定了
where T:new()
,要么根本没有这样的约束

我觉得我需要在默认构造函数中使用反射来实现这一点,但我希望不是这样

你不能强制约束,但你可以说

obj = Activator.CreateInstance<T>();
obj=Activator.CreateInstance();
它将调用
T
的默认构造函数

我知道这是可以做到的,因为.NET4.0中的惰性类不要求T在类级别是默认可构造的,但它具有与我的示例中类似的构造函数。我想知道至少有多懒


Lazy
要求指定一个委托,该委托返回实例
T
。基本上,它要求您指定一个
Func

您可以尝试使用
Activator

class MyClass<T> where T : class
{
    public MyClass()
    {
        obj = Activator.CreateInstance<T>();
    }
}
class MyClass,其中T:class
{
公共MyClass()
{
obj=Activator.CreateInstance();
}
}

好吧,你要么有约束,要么没有约束。事实证明,Lazy使用Activator创建了一个实例。以下是
Lazy
在出现版权问题的情况下如何处理删除的代码。

您只能在声明中包含约束,在声明中引入泛型类型参数

但是,您可以在非泛型类型上引入泛型方法:

公共类MyClass
{
公共静态MyClass Create(),其中T:class,new()
{
返回新的MyClass(()=>newt());
}
}
公共类MyClass,其中T:class
{
T-obj;
公共MyClass(分配器分配器)
{
obj=分配器();
}
}
(我个人只会使用
Func
,而不是声明一个单独的委托类型。)

然后您可以使用:

MyClass<Foo> foo = MyClass.Create<Foo>(); // Enforces the constraint
MyClass foo=MyClass.Create();//强制执行约束

另外:
Activator.CreateInstance()
将检查时间留给执行时间,这在我看来并不理想。
Activator.CreateInstance()
只检查它是否在运行时默认可构造?我不确定.NET BCL代码的许可证是否允许将其发布到internet上……注意到。把我锁起来,把钥匙扔掉!那是什么反应?+1丹尼尔。。。如果您已签署协议,Microsoft参考许可证允许您查看该许可证。。。这里的大多数人都没有。你可以强制约束-只是不能在构造函数中。在其他地方的泛型方法中引入它很好。@Jon Skeet:OP要求的约束不能在泛型类
MyClass
定义的类型参数
T
上实施。不能在类型本身上实施,也不能。。。但是您可以在非泛型类型上创建一个简单的泛型方法,并使用该方法而不是公共的无参数构造函数-请参阅我的答案。据我所知,要点是提供一种简单但编译时安全的方法,使用
T
的无参数构造函数创建
MyClass
的实例。我的答案就是这样。把我的答案改成这个。。。我读了一些关于
Activator.CreateInstance()
的书,实际上它没有在编译时检查默认构造(我更喜欢这样)。我选择了泛型工厂类。如果不使用'partial'关键字,如何定义MyClass两次?我不熟悉这种语法。@罗伯特·戴利:我没有两次声明过
MyClass
——我声明过
MyClass
(非泛型)和
MyClass
(带有一个类型参数的泛型)。它们是独立的类型,就像
Nullable
Nullable
是独立的类型一样。
public class MyClass
{
    public static MyClass<T> Create<T>() where T : class, new()
    {
        return new MyClass<T>(() => new T());
    }
}

public class MyClass<T> where T : class
{
    T obj;

    public MyClass(Allocator allocator)
    {
        obj = allocator();
    }
}
MyClass<Foo> foo = MyClass.Create<Foo>(); // Enforces the constraint