4

下面的“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,但是除了混淆同事之外,还有什么理由编写通用版本而不是“直截了当”的版本:)

4

8 回答 8

4

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

where T : MyClass

此外,使用通用版本,您不需要激活码:

return new T();

这是因为您已指定:

where T : new()

强制执行公共无参数构造函数的通用约束。

于 2011-07-14T14:28:00.340 回答
2

当然有区别。假设您有一个来自 MyClass 的第二个类:

class MyClass2 : MyClass { }

然后你可以做

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

你不能用其他功能做到这一点。

于 2011-07-14T14:29:02.040 回答
1

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

class MyClass { }
class MySpecializedClass : MyClass { } 
// etc.
于 2011-07-14T14:28:08.873 回答
1

有一个很大的区别:
非泛型版本只能返回 type 的实例MyClass,而泛型版本可以返回 type 的实例MyClass以及所有派生自MyClass!的类的实例。

于 2011-07-14T14:28:39.720 回答
0

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

于 2011-07-14T14:28:40.937 回答
0

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

它们的使用方式不同吗?

于 2011-07-14T14:30:08.803 回答
0

它们是不相同的。泛型允许像这样构建继承的类:

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>());
    }
}
于 2011-07-14T14:38:06.083 回答
-1

我不太确定,但泛型是 .NET 中的运行时特性。因此,非泛型方法并不等同于泛型方法,即使它被等效使用。由于它们是公开的,因此无法对其进行优化。

于 2011-07-14T14:28:45.403 回答