2010-04-27 28 views
3

我正在尋找一種解決方案來訪問類的「flatten」(最低)屬性值,並通過屬性名稱反射派生它。BindingFlags.DeclaredOnly避免派生類的不明確屬性的替代方法(AmbiguousMatchException)

即從ClassB的ClassC類型的訪問要麼Property1Property2

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 
    { 
    } 

使用簡單的反射工作,直到你有從overrired(即Property1虛擬財產ClassB)。然後你得到一個AmbiguousMatchException因爲搜索者不知道你是否想要主類或派生的屬性。

使用BindingFlags.DeclaredOnly避免AmbiguousMatchException但unoverrided虛擬性質或派生類屬性中省略(即Property2ClassB的)。

是否有替代這個可憐的解決方法:ClassCAmbiguousMatchException越來越Property1又回來了:

// 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); 

此外,這種解決方法不能解決的第二級屬性的反映。

我的想法:我沒有選擇,除了循環... Erk ...?

我開放給Emit,Lambda(是Expression.Call可以處理這個?)甚至是DLR解決方案。

謝謝!

回答

4

要做到這一點的唯一方法是枚舉所有的屬性並過濾出重複項。

我建議使用庫如Fasterflect來做到這一點。它解決了難題,併爲您提供了許多與標準反射相關的優點。

// find properties and remove duplicates higher up the hierarchy 
var properties = type.Properties(Flags.ExcludeBackingMembers); 
+1

+1爲Fasterflect,但我想它會比發射/表達式樹/ DLR代碼效率更低? – JoeBilly 2010-04-29 14:28:14

+2

它使用在封面下發射,但不用於查找(因爲這不是一個選項)。 – 2010-04-30 11:33:22

0

解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); 
} 

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