开发者

Unable to use generic method type <T> directly in Activator.CreateInstance

开发者 https://www.devze.com 2023-02-14 05:16 出处:网络
I\'m working on a generic method that will operate on custom collections that derive from CollectionBase. The generic method will do more than shown开发者_JAVA技巧 in my sample code, but this represen

I'm working on a generic method that will operate on custom collections that derive from CollectionBase. The generic method will do more than shown开发者_JAVA技巧 in my sample code, but this represents the essence of my question.

When I try the following I get a compiler error "Type parameter name is not valid at this point" with the argument T indicated in the CreateInstance() call:

public CollectionBase GetInstance<T>() where T : CollectionBase
    {
        return Activator.CreateInstance(T) as T;
    }

Instead, I have to use typeof(T) and pass it to CreateInstance:

 public CollectionBase GetInstance<T>() where T : CollectionBase
    {
        var targetType = typeof (T);
        return Activator.CreateInstance(targetType) as T;
    }

Not a big deal, but is there another way to declare my GetInstance method so that I can pass T directly into Activator.CreateInstance() as in the first examaple? And is my use of the generic type "T" in this case accepted practice?

I guess the essence of my question is that I assume T to be an actual type. But the compiler error and need to call typeof(T) seem to indicate it's instead the name of a type.


Yes, Activator.CreateInstance has an overload that accepts a generic type argument:

return Activator.CreateInstance<T>();


public CollectionBase GetInstance<T>() where T : CollectionBase
{
    return Activator.CreateInstance(typeof(T)) as T;
}

or:

public CollectionBase GetInstance<T>() where T : CollectionBase
{
    return Activator.CreateInstance<T>();
}


T is a type, not a System.Type instance.

Just like you need to write CreateInstance(typeof(Exception)) and not CreateInstance(Exception), so too you need to write CreateInstance(typeof(T)) and not CreateInstance(T)


or

public CollectionBase GetInstance<T>() where T : CollectionBase, new()
    {
        return new T();
    }


Say you have a class named MyClass.

If you want to use Activator.CreateInstance you'd still need to do Activator.CreateInstance(typeof(MyClass))

This is because MyClass actually references to the static version of MyClass (upon which you call it's static methods).

Instead typeof(MyClass) returns an instance of class System.Type.

EDIT

I know there is no real static version. That was just a construct to show the difference between MyClass and typeof(MyClass). Although I'm not completely wrong. If you have two apps sharing a class library containing MyClass and MyClass has a static member public class MyClass

{
    private static int myStaticMember = 0;
}

Then, due to .NET's sandboxing those two apps have seperate static versions of MyClass and do not share that member. In effect they each have a "static instance of MyClass" ... as contradictory as that may seem :).

0

精彩评论

暂无评论...
验证码 换一张
取 消