[英]How do I use reflection to execute an explicitly-implemented static abstract method
給定以下強制類實現 static 方法的接口...
public interface IMyInterface<T>
{
static abstract int GetNumber();
}
兩個類都有IMyInterfacee<T>
的兩個實現
public class MyClass1 : IMyInterface<Company>, IMyInterface<Person>
{
static int IMyInterface<Company>.GetNumber() => 1;
static int IMyInterface<Person>.GetNumber() => 2;
}
public class MyClass2 : IMyInterface<Company>, IMyInterface<Person>
{
static int IMyInterface<Company>.GetNumber() => 3;
static int IMyInterface<Person>.GetNumber() => 4;
}
當我有一個像這樣消耗 class 的方法時
public int GetNumbers(Type classType, Type genericType)
{
Type interfaceType = typeof(IMyInterface<>).MakeGenericType(genericType);
return ??????
}
我將如何實現GetNumbers
以便我可以這樣調用它
GetNumbers(typeof(MyClass1), typeof(Company)); // returns 1
GetNumbers(typeof(MyClass1), typeof(Person)); // returns 2
GetNumbers(typeof(MyClass2), typeof(Company)); // returns 3
GetNumbers(typeof(MyClass2), typeof(Person)); // returns 3
您可以使用接口映射 ( Type.GetInterfaceMap
) 來查找實現接口的方法:
int GetNumbers(Type classType, Type genericType)
{
Type interfaceType = typeof(IMyInterface<>).MakeGenericType(genericType);
// todo - check that class implements interface
var interfaceMapping = classType.GetInterfaceMap(interfaceType);
MethodInfo? methodInfo = null;
for (int i = 0; i < interfaceMapping.InterfaceMethods.Length; i++)
{
var sourceMethod = interfaceMapping.InterfaceMethods[i];
// simple predicate to find by name
// possibly check that parameters are empty and return type is int
if (sourceMethod.Name.Equals(nameof(IMyInterface<object>.GetNumber), StringComparison.Ordinal))
{
methodInfo = interfaceMapping.TargetMethods[i];
break;
}
}
if (methodInfo is null)
{
throw new Exception("Should not happen");
}
return (int)methodInfo.Invoke(null, null);
}
由於缺少代表,我無法在 Guru Stron 的回答下方寫下常規評論,但GetInterfaceMap
目前對於包含static abstract
成員或static virtual
成員的接口已損壞:無條件傳遞此類接口的類型會引發VerificationException
。 請參閱do.net/runtime#73658 。
此外,還有另外兩個與static abstract
鏈接的接口的反射問題,似乎大多數反射堆棧根本不適用於此類接口類型。 鑒於此,我能給出的唯一好的答案是“你不能這樣做(直到它被修復(希望在 .NET 7 服務更新中,但我沒有屏住呼吸))”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.