如何使用已知类型作为参数使用泛型创建泛型类?

时间:2019-04-11 13:55:55

标签: c#

假设我有一个非泛型类NonGenericClass,并且我想有一个泛型类GenericClass<T>,其方法将返回T<NonGenericClass>

Pseduo代码示例:

public class NonGeneric Class {}

public class GenericClass<T>  
{
    public T<NonGenericClass> foo()
    {
        return new T<NonGenericClass>();
    } 
}

我将如何在c#中完成此操作?

1 个答案:

答案 0 :(得分:1)

public class NonGenericClass {}

public class OtherGenericClass<T>{}

public class GenericClass<T,T2>
    where T: OtherGenericClass<T2>, new()
    where T2: NonGenericClass
{
    public T Foo()
    {
        return new T();
    }
}

所有这些约束实际上都意味着某种意义,因此,如果您实际上需要所有这些约束,这将很有意义。试图想象它们只会使我头晕目眩。即使这些都是带有真实名称的真实类,并且所有这些都达到了目的,但我在编写它后不久就很难理解它,而下一个开发人员会讨厌我。

这意味着Foo()将始终返回OtherGenericClass<T2>,而T2将始终为NonGenericClass

如果您尝试对从这些类型中的任何一种继承的类执行任何操作,则将出现各种有关协方差的编译器错误,这些错误会使您大吃一惊。我已经记录了here的过程。您越努力使它发挥作用,效果就会越差。

我怀疑这种情况的发生是因为我们在编写需要的代码之前尝试创建这些通用类。否则,我们将只编写我们现在需要的类,并且也许稍微重构一下即可使用泛型(如果发现它们有意义)。

发生的事情是,让我们的泛型进行编译,然后开始编写依赖于这些类的代码,那时我们才意识到所构建的并不是我们所需要的。或复杂性感染依赖于这些类的代码,现在它们也需要各种通用约束。最终,我们碰壁了,要么无法编译,要么忘记了我们试图完成的任务,要么都没有。

new()约束仅仅是因为该方法返回new T()。除非没有该约束,否则它将不会编译,该约束指定T()必须是具有无参数构造函数的东西。