简体   繁体   中英

public T GetMyClass<T>() where T : MyClass, new() { /* is this pointless? */ }

are the two methods in the class "Confused" below the same?

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

They produce different IL, but is there any reason to write the generic version other than the 'straight up' version other than to confuse the heck out of collegues:)

If you write the generic version, you can instantiate and return derived classes:

where T: MyClass

Also, with the generic version you don't need the activation code:

return new T();

This is because you have specified:

where T: new()

The generic constraint enforcing a public parameterless constructor.

Sure there's a difference. Let's say you have a second class deriving from MyClass:

class MyClass2 : MyClass { }

Then you can do

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

You can't do that with the other function.

MyClass could be a base class (or an interface IMyClass ). The generic version with the constraint says you want this function to work for any class derived from (or implementing) a common base or interface and to return the result as that derived class, not as the base.

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

There is a very big difference:
The non generic version can only return instances of type MyClass , whereas the generic version can return instances of type MyClass and all classes derived from MyClass !

No. They are not the same. The first will only ever construct a MyClass object, and the second will construct any object that is a MyClass or a descendent of MyClass , based on the type parameter.

They would give the same result ONLY if you called .GetMyClass<MyClass>() . However, I presume the extra method has been created to allow for creation of other classes? If not, then they're the same, so one's redundant (and I'd get rid of the generic version as has overhead inside the assembly).

Are they being used differently?

They are not the same. The generic allows inherited classes to be built as well like this:

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

I'm not quite sure, but Generics are a runtime feature in .NET. Therefore, the non-generic method isn't equivalent to the generic one, even though it is used equivalently. As they're public, this can't be optimized away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM