我有一个带new()约束的泛型方法。我使用抽象类型调用此方法,当然,它不会编译。我希望保持调用泛型,但希望我可以在运行时确定派生类是什么,以满足编译器。电话会看起来像这样:
var result = MyGenericMethod<FindDerivedClass(myAbstractClass)>();
我尝试过typeof(),但这似乎不起作用。
答案 0 :(得分:1)
我有一个带new()约束的泛型方法。我使用抽象类型调用此方法,当然,它不会编译。我希望保持调用泛型,但希望我能在运行时确定派生类是什么,以满足编译器。
这不是编译,而是您需要担心的实际语义。你有一个new()
约束的方法 - 这表明该方法需要实例化它传递的T
的对象。您希望将抽象类作为T
传递 - 但这意味着什么?泛型方法在想要实例化时应该怎么做?
您需要确定这些问题的答案:如果该方法不需要实例化T
,为什么它有new()
约束?如果它确实需要实例化一个T
,那么如果你以某种方式设法使编译器接受一个抽象类T
,它应该做什么?
答案 1 :(得分:1)
要在运行时使用泛型,您需要使用反射 - 在程序集中查看所需的所有类型(您可以使用Type.IsSubclassOf),为通用方法获取MethodInfo想要对其进行调用,然后使用MethodInfo.MakeGenericMethod替换为您要调用的实际类型,并使用Invoke
进行调用答案 2 :(得分:0)
糟糕的想法,您想要采用DerivedClass吗?如果有多个怎么办?如果没有DerivedClass会怎么样?
您可以将类型作为类类型参数传递,而不是方法类型参数:
abstract class MyAbstractClass<T> where T : MyAbstractClass<T>, new()
{
T MyMethod() { return new T(); }
}
答案 3 :(得分:0)
如果MyGenericMethod
是实例方法:
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();
如果MyGenericMethod
是静态方法:
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();
如果MyGenericMethod
返回值,则使用Func<ReturnType>
代替Action
代理。