簡體   English   中英

如何使用反射來執行顯式實現的 static 抽象方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM