简体   繁体   中英

Determining Derived Class Type At Runtime

I have a generic method with a new() constraint. I have a call to this method with an abstract type which, of course, won't compile. I wish to keep the call generic, but was hoping I could determine at runtime what the derived class is so as to satisfy the compiler. The call would look something like this:

var result = MyGenericMethod<FindDerivedClass(myAbstractClass)>();

I tried typeof() but this doesn't seem to work.

I have a generic method with a new() constraint. I have a call to this method with an abstract type which, of course, won't compile . I wish to keep the call generic, but was hoping I could determine at runtime what the derived class is so as to satisfy the compiler .

It's not the compilation, but rather the actual semantics you need to worry about. You have a method with a new() constraint - this suggests that the method needs to instantiate an object of the T it is passed. You want to pass an abstract class as the T - but what would this mean? What should the generic method do when it wants to instantiate?

You need to decide the answers to these questions: If the method doesn't need to instantiate a T , why does it have a new() constraint? If it does need to instantiate a T , what's it supposed to do if you somehow manage to get the compiler to accept an abstract class as T ?

要在运行时使用泛型,您需要使用反射-在程序集中的所有类型中查找所需的类型(可以使用Type.IsSubclassOf ),获取要在其上调用的泛型方法的MethodInfo ,然后替换为您想使用MethodInfo.MakeGenericMethod对其进行调用的实际类型,并使用Invoke对其进行调用

Bad idea, which DerivedClass do you want to take ? What if there is more than one ? what if there is no DerivedClass ?

You may pass the type as class type parameter and not method type parameter :

abstract class MyAbstractClass<T> where T : MyAbstractClass<T>, new()
{
  T MyMethod() { return new T(); }
}

If MyGenericMethod is an instance method:

var method = typeof(this).GetMethod("MyGenericMethod", Type.EmptyTypes);
method = method.MakeGenericMethod(new Type[] { FindDerivedClass(myAbstractClass) });
Action action = (Action)Delegate.CreateDelegate(typeof(Action), this, method);
action();

If MyGenericMethod is a static method:

var method = typeof(TypeWithGenericMethod).GetMethod("MyGenericMethod", BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null);
method = method.MakeGenericMethod(new Type[] { FindDerivedClass(myAbstractClass) });
Action action = (Action)Delegate.CreateDelegate(typeof(Action), method);
action();

If MyGenericMethod returns a value, then use Func<ReturnType> in place of the Action delegate.

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