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

标签 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;
}

此类要求类型 T 在所有情况下都是引用类型。对于默认构造函数,我们希望通过其默认构造函数实例化 T。我想放一个 where T : new()在我的默认构造函数上,像这样:

public MyClass()
    where T : new()
{
    obj = new T();
}

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

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

我觉得我需要在默认构造函数中为此使用反射,但我希望不需要。

我知道这是可以做到的,因为 Lazy<T> .NET 4.0 中的类不要求 T 在类级别是默认可构造的,但它具有类似于我的示例中的构造函数。我想知道如何Lazy<T>至少做到了。

最佳答案

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

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

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();
    }
}

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

然后你可以使用:

MyClass<Foo> foo = MyClass.Create<Foo>(); // Enforces the constraint

关于c# - C#中构造函数的where子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5978554/

相关文章:

c# - 具有空访问器的属性

c# - MVC5 + Microsoft 帐户 (Live ID) + IIS = redirect_uri 无效

c# - 如何使用 NinjectHttpApplication(无 nuget)在 HttpModule 中注入(inject)依赖项?

c# - 无法从 EC2 实例元数据服务检索凭据

Java:当 B 实现 A 时从 List<B> 转换为 List<A>?

斯卡拉,猫。有人可以解释什么是 `F` 以及它从何而来?

c# - 标签可见性。折叠在空白内容WPF MVVM上

c# - 接口(interface)声明和通用约束

Java:试验泛型

c# - 定义嵌套的无界泛型类型