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

voi*_*ter 9 c# generics

所以这就是我想要做的.

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

这是一个例子:

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

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

    T obj;
}
Run Code Online (Sandbox Code Playgroud)

此类要求类型T在所有情况下都是reftype.对于默认构造函数,我们希望通过其默认构造函数实例化T.我想where T : new()在我的默认构造函数上添加一个,如下所示:

public MyClass()
    where T : new()
{
    obj = new T();
}
Run Code Online (Sandbox Code Playgroud)

但是,这不是有效的C#.基本上我只想在类型T上添加约束,只有在使用MyClass()的默认构造函数时才有默认构造函数.

在MyClass的第二个构造函数中,我们让用户确定如何使用自己的分配方法为T分配,所以很明显,MyClass在所有情况下都不能强制执行T是默认构造.

我有一种感觉,我需要在默认构造函数中使用反射,但我希望不会.

我知道这可以做到,因为Lazy<T>.NET 4.0中的类不要求T在类级别上是默认可构造的,但它的构造函数与我的示例中的构造函数类似.我想知道Lazy<T>它至少是怎么回事.

Jon*_*eet 9

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

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

(我个人只是使​​用Func<T>而不是声明一个单独的委托类型顺便说一句.)

然后你可以使用:

MyClass<Foo> foo = MyClass.Create<Foo>(); // Enforces the constraint
Run Code Online (Sandbox Code Playgroud)


jas*_*son 7

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

不能通过约束来强制执行此操作T.您可能where T : new()是在定义中指定的情况,MyClass<T>或者根本没有这样的约束.

我有一种感觉,我需要在默认构造函数中使用反射,但我希望不会.

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

obj = Activator.CreateInstance<T>();
Run Code Online (Sandbox Code Playgroud)

这将调用默认构造函数T.

我知道这可以做到,因为.NET 4.0中的Lazy类不需要T在类级别默认构造,但它的构造函数与我的示例中的构造函数类似.我想知道Lazy至少如何做到这一点.

Lazy<T>要求您指定返回实例的委托T.基本上,它需要您指定一个Func<T>.