获取接口属性的运行时getter

时间:2017-03-06 23:12:45

标签: c# reflection

声明:

interface I
{
    int i { get; set; }
}

class C : I
{
    public int i { get; set; }
}

代码:

C c = new C();
c.i = 10;
PropertyInfo pi1 =
    c.
    GetType().
    GetInterfaces().
    SelectMany(t => t.GetProperties()).
    ToArray()[0];
PropertyInfo pi2 =
    c.
    GetType().
    GetProperties()[0];
object v1 = pi1.GetValue(c);
object v2 = pi2.GetValue(c);

嘿,v1 == v2pi1 != pi2,但GetValue显然会调用相同的方法。我如何在代码中知道pi1pi2调用相同的方法主体?

1 个答案:

答案 0 :(得分:4)

您可以使用Type.GetInterfaceMap()来获取接口成员与特定类型的实现成员之间的映射。这是一个例子:

using System;
using System.Linq;
using System.Threading;

interface I
{
    int Value { get; set; }
}

class C : I
{
    public int Value { get; set; }
}

public class Test
{
    static void Main()
    {
        var interfaceGetter = typeof(I).GetProperty("Value").GetMethod;
        var classGetter = typeof(C).GetProperty("Value").GetMethod;
        var interfaceMapping = typeof(C).GetInterfaceMap(typeof(I));

        var interfaceMethods = interfaceMapping.InterfaceMethods;
        var targetMethods = interfaceMapping.TargetMethods;
        for (int i = 0; i < interfaceMethods.Length; i++)
        {
            if (interfaceMethods[i] == interfaceGetter)
            {
                var targetMethod = targetMethods[i];
                Console.WriteLine($"Implementation is classGetter? {targetMethod == classGetter}");
            }
        }
    }
}

这会打印Implementation is classGetter? True - 但是如果您更改代码以便提取I.Value 没有调用C.Value,例如通过添加基类,C.Value是新属性,而不是I.Value的实现:

interface I
{
    int Value { get; set; }
}

class Foo : I
{
    public int Value { get; set; }
}

class C : Foo
{
    public int Value { get; set; }
}

...然后会打印Implementation is classGetter? False