代码之家  ›  专栏  ›  技术社区  ›  JoeBilly

bindingFlags.declaredOnly可选,以避免派生类的属性不明确(ambiguousMatchException)

  •  3
  • JoeBilly  · 技术社区  · 15 年前

    我正在寻找一个解决方案来访问类的“Flatten”(最低)属性值及其通过属性名反射派生的值。

    IE访问 财产1 财产2 来自 乙类 小精灵 类型:

       public class ClassA
        {
            public virtual object Property1 { get; set; }
    
            public object Property2 { get; set; }
        }
        public class ClassB : ClassA
        {
            public override object Property1 { get; set; }
        }
        public class ClassC : ClassB
        {
        }
    

    使用简单的反射可以工作,直到您的虚拟属性被重写(即 财产1 乙类 )然后你得到一个 含糊不清的匹配异常 因为搜索者不知道您想要的是主类的属性还是派生的属性。

    使用bindingFlags.declaredOnly避免出现含糊不清的MatchException,但未覆盖的虚拟属性或派生类属性被忽略(即 财产2 乙类 )

    除了这种糟糕的解决方案,还有别的办法吗?

    // Get the main class property with the specified propertyName
    PropertyInfo propertyInfo = _type.GetProperty(propertyName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
    
        // If not found, get the property wherever it is
        if (propertyInfo == null)
                propertyInfo = _type.GetProperty(propertyName);
    

    此外,此解决方案无法解决第二级属性的反射:获取 财产1 小精灵 含糊不清的匹配异常 回来了。

    我的想法:除了循环我别无选择…尔克…???

    我可以发出lambda(表达式是.call可以处理它吗?)即使是DLR解决方案。

    谢谢!

    2 回复  |  直到 11 年前
        1
  •  4
  •   Morten Mertner    15 年前

    唯一的方法是枚举所有的属性并过滤掉重复的属性。

    我建议使用像这样的图书馆 Fasterflect 这样做。它解决了困难的问题,并为您提供了许多优于使用标准反射所能做到的功能。

    // find properties and remove duplicates higher up the hierarchy
    var properties = type.Properties( Flags.ExcludeBackingMembers );
    
        2
  •  0
  •   JoeBilly    11 年前

    带紧固件的解决方案选择:

    foreach (PropertyInfo propertyInfo in objType.Properties(Flags.ExcludeBackingMembers | Flags.Public | Flags.Static | Flags.Instance))
    {
        FasterflectPropertyValue(propertyInfo.Name, obj);
    }
    
    private static object FasterflectPropertyValue(string propertyName, object obj)
    {
        return obj.GetPropertyValue(propertyName);
    }
    

    Reflection from Class1 - 1 loops :3602674ticks
    Reflection from Class2 - 1 loops :2940541ticks
    Reflection from Class3 - 1 loops :1035300ticks
    Reflection from Class1 - 100 loops :2ms
    Reflection from Class2 - 100 loops :2ms
    Reflection from Class3 - 100 loops :3ms
    Reflection from Class1 - 10000 loops :274ms
    Reflection from Class2 - 10000 loops :284ms
    Reflection from Class3 - 10000 loops :295ms
    Fasterflect from Class1 - 1 loops :44ms
    Fasterflect from Class2 - 1 loops :2508656ticks
    Fasterflect from Class3 - 1 loops :2314142ticks
    Fasterflect from Class1 - 100 loops :3223064ticks
    Fasterflect from Class2 - 100 loops :5056514ticks
    Fasterflect from Class3 - 100 loops :5166725ticks
    Fasterflect from Class1 - 10000 loops :96ms
    Fasterflect from Class2 - 10000 loops :138ms
    Fasterflect from Class3 - 10000 loops :162ms