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.