c# - 获取接口(interface)属性的运行时 getter

标签 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 调用了相同的方法体?

最佳答案

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

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?错误

关于c# - 获取接口(interface)属性的运行时 getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42637329/

相关文章:

C#合并文件可直接访问

c# - ANTLR AST 建筑 : root node as string instead of character

c# - 使用反射将项目添加到通用列表/集合

java - 如何在没有 Java 9+ 非法访问警告的情况下从进程获取 pid?

c# - DataTable Linq 连接多列

c# - 由于缺少程序集,Dotnet 格式未在 Github Action 中运行

java - 在工厂中使用反射

go - 从 JSON 字符串中恢复满足定义接口(interface)的结构

java - 如何用 guice 替换反射?

c# - 用户控件数据上下文绑定(bind)