如何忽略使用反射继承的类的所有隐藏属性?

时间:2019-04-05 17:58:27

标签: c# system.reflection

我遇到一个问题,我需要从一个对象获取所有属性,然后对这些属性进行排序,然后将某些属性的值发送到另一个服务。这是代码示例:

public class Class1
{
    public string A { get; set; }
    public bool B  { get; set; }
}

public class Class2 : Class1 
{
    public new bool? B { get; set; }
    public bool C { get; set; }
}

我需要获取Class2的所有属性,但是当使用Class2.GetType()。GetProperties()时,结果包含Class2 AND Class1中的B。这引起了我的问题,因为在遍历每个属性时,我向B发送两次,一次B的默认值是false,因为它从未设置过,而另一个默认值是由我的服务设置的。我需要结果包含Class2中的B,Class1中的A和Class2中的C,但忽略Class1中的B,因为它已被new关键字隐藏。

我尝试浏览可以使用的绑定标志,但这没有帮助。我能找到的最接近的标志是BindingFlags.DeclaredOnly标志,但是它从Class1中排除了A,因此它对我不起作用。

如果原始属性已隐藏,我将如何忽略呢?

3 个答案:

答案 0 :(得分:2)

如果我了解您的权利,则需要Class2中的所有属性以及Class1中未重新定义的Class2的所有属性

您可以通过两次调用GetProperties来实现:首先选择Class2中定义的所有内容,然后访问Class1的类型并添加所有缺失的内容

var type = typeof(Class2);
var list = new List<PropertyInfo>();
list.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly));

var baseType = type.BaseType;
if (baseType != null)
{
    foreach (var propertyInfo in baseType.GetProperties())
    {
        if (list.All(p => p.Name != propertyInfo.Name))
            list.Add(propertyInfo);
    }
}

如果您打印该列表

foreach (var propertyInfo in list)
    Console.WriteLine($"From {propertyInfo.DeclaringType} > '{propertyInfo.Name}':{propertyInfo.PropertyType}");

您将看到类似的内容:

  

来自Class2>'B':System.Nullable`1 [System.Boolean]
  从Class1>'A':System.String

答案 1 :(得分:1)

您可以使用LINQ查询来过滤隐藏的属性。

var allProps = typeof(Class2).GetProperties(
        BindingFlags.Instance | BindingFlags.Public
);

var thePropsYouWant = 
        from p in allProps
        group p by p.Name into g
        select g.OrderByDescending(t => t.DeclaringType == typeof(Class2)).First();

看到它在这里运行:https://dotnetfiddle.net/V5sGIs

答案 2 :(得分:0)

基于LINQ的简单解决方案,适用于所有类层次结构:

   var propertiesWithoutHiddenOnes = GetProperties(objectToUpdate.GetType())
            .GroupBy(prop => prop.Name)
            .Select(group => group.Aggregate(
                     (mostSpecificProp, other) => mostSpecificProp.DeclaringType.IsSubclassOf(other.DeclaringType) ? mostSpecificProp : other))