公共T GetMyClass() where T: MyClass, new(){/*这是毫无意义的吗?* /}

本文关键字:毫无意义 GetMyClass where new 公共 MyClass | 更新日期: 2023-09-27 18:02:00

下面的"Confused"类中的两个方法是相同的吗?

class MyClass
{
    public override string ToString()
    {
        return "I am confused now";
    }
}
class Confused
{    
    public MyClass GetMyClass()
    {
        return new MyClass();
    }
    public T GetMyClass<T>() where T : MyClass, new()
    {
        return System.Activator.CreateInstance<T>();
    }
}
class Program
{
    static void Main()
    {
        Confused c = new Confused();
        System.Console.WriteLine(c.GetMyClass());
        System.Console.WriteLine(c.GetMyClass<MyClass>());
    }
}

它们产生不同的IL,但是除了"直接"的版本之外,还有什么理由写通用版本呢?

如果您编写泛型版本,则可以实例化并返回派生类:

where T : MyClass

同样,对于通用版本,您不需要激活码:

return new T();

这是因为您指定了:

where T : new()

强制公共无参数构造函数的泛型约束。

公共T GetMyClass<T>() where T: MyClass, new(){/*这是毫无意义的吗?* /}

当然有区别。假设你有第二个类派生自MyClass:

class MyClass2 : MyClass { }

然后你可以做

MyClass2 myClass2 = confused.GetMyClass<MyClass2>();

其他函数不能这样做

MyClass可以是基类(或接口IMyClass)。带有约束的泛型版本表示,您希望此函数适用于从公共基类或接口派生(或实现)的任何类,并将结果作为该派生类返回,而不是作为基类返回。

class MyClass { }
class MySpecializedClass : MyClass { } 
// etc.

有很大的区别:
非泛型版本只能返回MyClass类型的实例,而泛型版本可以返回MyClass类型的实例和所有从MyClass派生的类!

No。它们不一样。第一个将只构造一个MyClass对象,第二个将根据类型参数构造任何MyClassMyClass的后代对象。

它们只会在调用.GetMyClass<MyClass>()时给出相同的结果。但是,我认为创建额外的方法是为了允许创建其他类。如果不是,那么它们是相同的,所以一个是多余的(我将摆脱通用版本,因为它在程序集中有开销)。

它们被不同地使用了吗?

它们不一样。泛型允许像这样构建继承类:

class MyClass
{
    public override string ToString()
    {
        return "I am confused now";
    }
}
class InheritedClass : MyClass
{
}
class Confused
{
    public MyClass GetMyClass()
    {
        return new MyClass();
    }
    public T GetMyClass<T>() where T : MyClass, new()
    {
        return System.Activator.CreateInstance<T>();
    }
}
class Program
{
    static void Main()
    {
        Confused c = new Confused();
        System.Console.WriteLine(c.GetMyClass());
        System.Console.WriteLine(c.GetMyClass<MyClass>());
        System.Console.WriteLine(c.GetMyClass<InheritedClass>());
    }
}

我不太确定,但是泛型是。net中的一个运行时特性。因此,非泛型方法并不等同于泛型方法,即使它们是等价使用的。