C# BindingFlags.DeclaredOnly可避免派生类属性不明确的替代方法(AmbiguousMatchException)
我正在寻找一种解决方案,通过属性名称的反射来访问类及其派生的“扁平”(最低)属性值 ie从ClassB或ClassC类型访问Property1或Property2: 使用简单反射可以一直工作,直到您拥有过度使用的虚拟属性(即ClassB中的Property1)。然后您会得到一个含糊不清的UsMatchException,因为搜索者不知道您想要的是主类的属性还是派生类的属性 使用BindingFlags.Declared只能避免含糊不清的UsMatchException,但未覆盖的虚拟属性或派生类属性会被忽略(即ClassB中的Property2) 除了这一糟糕的解决办法,还有其他办法吗C# BindingFlags.DeclaredOnly可避免派生类属性不明确的替代方法(AmbiguousMatchException),c#,.net,reflection,C#,.net,Reflection,我正在寻找一种解决方案,通过属性名称的反射来访问类及其派生的“扁平”(最低)属性值 ie从ClassB或ClassC类型访问Property1或Property2: 使用简单反射可以一直工作,直到您拥有过度使用的虚拟属性(即ClassB中的Property1)。然后您会得到一个含糊不清的UsMatchException,因为搜索者不知道您想要的是主类的属性还是派生类的属性 使用BindingFlags.Declared只能避免含糊不清的UsMatchException,但未覆盖的虚拟属性或派生类
// 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);
此外,此解决方案无法解决第二级属性的反射:从ClassC获取Property1,而含糊不清的MatchException又回来了
我的想法:除了循环,我别无选择。。。呃
我对Emit、Lambda(是表达式.Call可以处理这个问题吗?)甚至DLR解决方案都持开放态度
谢谢 唯一的方法是枚举所有属性并过滤掉重复的属性 我建议你使用一个像这样的图书馆。它解决了困难的问题,并为您提供了比标准反射更好的特性
// find properties and remove duplicates higher up the hierarchy
var properties = type.Properties( Flags.ExcludeBackingMembers );
使用Fasterflect的解决方案:
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);
}
来自Class1-1循环的反射:3602674ticks
来自Class2-1循环的反射:2940541滴答声
来自Class3-1循环的反射:1035300ticks
来自Class1-100循环的反射:2ms
来自Class2-100循环的反射:2ms
来自Class3-100循环的反射:3ms
来自Class1-10000循环的反射:274ms
来自Class2-10000循环的反射:284ms
来自Class3-10000循环的反射:295ms
从Class1-1循环中快速选择:44ms
Fasterflect from Class2-1循环:2508656ticks
Fasterflect from Class3-1循环:2314142滴答声
Fasterflect from Class1-100循环:3223064次
Fasterflect from Class2-100循环:5056514个滴答声
Fasterflect from Class3-100循环:5166725ticks
从Class1-10000循环中快速选择:96ms
从Class2-10000循环中快速选择:138ms
Fasterflect from Class3-10000 loops:162ms
+1用于Fasterflect,但我想它的效率不如emit/expression tree/DLR代码?它使用emit-under-of-cover,但不用于查找(因为这不是一个选项)。
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);
}