如何确定属性是否被覆盖?

Ben*_*min 11 .net c# reflection types propertyinfo

我在做一个项目,在那里我需要注册的所有属性,因为系统是如此巨大,将需要大量的工作来注册的一切,我希望依赖XAML的目的属性.

目标是找到树顶部的所有属性.

所以基本上

public class A{
    public int Property1 { get; set; }
}

public class B : A{
    public int Property2 { get; set; }
    public virtual int Property3 { get; set; }
}

public class C : B{
    public override int Property3 { get; set; }
    public int Property4 { get; set; }
    public int Property5 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

最终结果将是这样的

A.Property1  
B.Property2  
B.Property3  
C.Property4  
C.Property5  
Run Code Online (Sandbox Code Playgroud)

如果您注意到我不想接受被覆盖的属性,因为我搜索属性的方式如果我做这样的事情

C.Property3例如,它找不到它会检查C的基本类型,它会找到它.

这就是我到目前为止所拥有的.

public static void RegisterType( Type type )
{
    PropertyInfo[] properties = type.GetProperties( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.GetProperty | BindingFlags.SetProperty );

    if ( properties != null && properties.Length > 0 )
    {
        foreach ( PropertyInfo property in properties )
        {
            // if the property is an indexers then we ignore them
            if ( property.Name == "Item" && property.GetIndexParameters().Length > 0 )
                continue;

            // We don't want Arrays or Generic Property Types
            if ( (property.PropertyType.IsArray || property.PropertyType.IsGenericType) )
                continue;

            // Register Property
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要的是以下内容:

  • 公共属性,未被覆盖,不是静态的,不是私有的
  • 允许获取和设置属性
  • 它们不是数组或泛型类型
  • 它们是树的顶部,即示例中的C类是最高的(属性列表示例正是我正在寻找的)
  • 它们不是索引器属性(此[索引])

Jos*_*osh 23

为了忽略继承的成员,您可以使用您已经在做的BindingFlags.DeclaredOnly标志.

但是当覆盖属性时,派生类会重新声明它们.诀窍是然后查看它们的访问器方法以确定它们是否实际上已被覆盖.

Type type = typeof(Foo);

foreach ( var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) {
    var getMethod = property.GetGetMethod(false);
    if (getMethod.GetBaseDefinition() == getMethod) {
        Console.WriteLine(getMethod);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果覆盖该属性,则其'getter'MethodInfo将从中返回不同的MethodInfo GetBaseDefinition.