我有一個帶有new()約束的泛型方法。我用一個抽象類型來調用這個方法,當然這個類型不會被編譯。我希望保持通用調用,但希望我可以在運行時確定派生類是如何滿足編譯器的。電話看起來是這樣的:在運行時確定派生類的類型
var result = MyGenericMethod<FindDerivedClass(myAbstractClass)>();
我試過typeof(),但這似乎並不奏效。
我有一個帶有new()約束的泛型方法。我用一個抽象類型來調用這個方法,當然這個類型不會被編譯。我希望保持通用調用,但希望我可以在運行時確定派生類是如何滿足編譯器的。電話看起來是這樣的:在運行時確定派生類的類型
var result = MyGenericMethod<FindDerivedClass(myAbstractClass)>();
我試過typeof(),但這似乎並不奏效。
壞主意,你想採用哪種DerivedClass?如果有多個呢?如果沒有DerivedClass會怎麼樣?
您可以通過類型爲類類型的參數,而不是方法類型參數:
abstract class MyAbstractClass<T> where T : MyAbstractClass<T>, new()
{
T MyMethod() { return new T(); }
}
我有一個新的()約束的通用方法。我有一個抽象類型的這種方法調用,當然,不會編譯。我希望保持通用調用,但希望我可以在運行時確定派生類是如何滿足編譯器。
這不是彙編,而是實際的語義你需要擔心。你有一個new()
約束的方法 - 這表明該方法需要實例化它傳遞的T
的對象。你想通過一個抽象類作爲T
- 但這意味着什麼?泛型方法在實例化時應該做什麼?
您需要決定這些問題的答案:如果該方法不需要實例化一個T
,爲什麼它有new()
約束?如果它確實需要實例化一個T
,如果你以某種方式設法讓編譯器接受一個抽象類T
,它應該做些什麼?
要在運行時使用泛型,您需要使用反射 - 查看程序集中的所有類型(您可以使用Type.IsSubclassOf),獲取MethodInfo作爲要調用的泛型方法,然後替代你想MethodInfo.MakeGenericMethod調用它的實際類型和使用Invoke
如果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
委託。