2012-07-12 50 views
21

如何獲取我的財產?目前出現Ambiguous match found錯誤,請參閱代碼中的註釋行。GetProperty反射結果在新屬性中發現「模糊匹配」

public class MyBaseEntity 
{ 
    public MyBaseEntity MyEntity { get; set; } 
} 

public class MyDerivedEntity : MyBaseEntity 
{ 
    public new MyDerivedEntity MyEntity { get; set; } 
} 

private static void Main(string[] args) 
{ 
    MyDerivedEntity myDE = new MyDerivedEntity(); 

    PropertyInfo propInfoSrcObj = myDE.GetType().GetProperty("MyEntity"); 
    //-- ERROR: Ambiguous match found 
} 
+1

運行時錯誤或編譯時錯誤? – 2012-07-12 01:07:08

+1

@Valamas請重新考慮選定的答案。許多人會在這裏使用像if(winform.GetType()。GetProperty(「Items」)!= null){..}這樣的條件結構,在這種情況下,僅僅使用Linq來切換異常...... – 2013-09-27 21:01:01

回答

24

Type.GetProperty

情況,其中發生AmbiguousMatchException ...

...派生類型聲明隱藏具有相同名稱繼承的屬性的屬性,通過使用新的改性劑

如果您運行以下程序

var properties = myDE.GetType().GetProperties().Where(p => p.Name == "MyEntity"); 

您將看到兩個PropertyInfo對象被返回。一個用於MyBaseEntity,另一個用於MyDerivedEntity。這就是爲什麼你收到發現模糊匹配錯誤。

你可以得到PropertyInfoMyDerivedEntity這樣的:

PropertyInfo propInfoSrcObj = myDE.GetType().GetProperties().Single(p => 
    p.Name == "MyEntity" && p.PropertyType == typeof(MyDerivedEntity)); 
+2

+1。很好的解釋。爲了以防萬一,我添加了RTFM鏈接。 – 2012-07-12 01:31:27

+0

奇妙的東西!我將它簡化爲'type.GetProperties()。首先(p => p.Name ==「MyEntity」)'所有測試都是綠色的! – 2012-07-12 01:36:15

+1

無論「First」還是「Single」,都會在沒有元素出現時拋出異常**以開頭! – 2013-09-27 20:51:48

5

凱文已經指出的問題,但你並不需要複雜的語句,或LINQ爲:

PropertyInfo propInfoSrcObj = myDE.GetType(). 
    GetProperty("MyEntity", typeof(MyDerivedEntity)); 
16

對於物業:

MemberInfo property = myDE.GetProperty(
    "MyEntity", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); 

對於方法:

MemberInfo method = typeof(String).GetMethod(
    "ToString", 
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, 
    null, 
    new Type[] { },// Method ToString() without parameters 
    null); 

BindingFlags .DeclaredOnly - 指定只應考慮在提供的類型層次結構中聲明的成員。不考慮繼承的成員。

0

我與我的LocationKey對象的MsgPack序列化有此問題。最終成爲我在LocationKey類中定義的運算符。在嘗試序列化時,定義這兩個運算符都會導致DefaultContext.GetSerializer(obj.GetType());發現模糊匹配。拆除一組操作員後,問題就消失了。

public static bool operator ==(int key1, LocationKey key2) 
{ 
    return key1 == key2.Value; 
} 

public static bool operator !=(int key1, LocationKey key2) 
{ 
    return key1 != key2.Value; 
} 

public static bool operator ==(LocationKey key1, int key2) 
{ 
    return key1.Value == key2; 
} 

public static bool operator !=(LocationKey key1, int key2) 
{ 
    return key1.Value != key2; 
} 
9

歧義發生,因爲在MyDerivedEntitynew聲明。爲了克服這一點,你可以使用LINQ:

var type = myObject.GetType(); 
var colName = "MyEntity"; 
var all = type.GetProperties().Where(x => x.Name == colName); 
var info = all.FirstOrDefault(x => x.DeclaringType == type) ?? all.First(); 

這會搶了財物出來的派生類型,如果它存在,否則基地。如果需要,這可以很容易地翻轉。

+1

這是更通用和可擴展的解決方案。 – it3xl 2016-05-31 09:59:22

+1

非常有效的解決方案!但是我擔心這些屬性的順序不能保證:_M:System.Type.GetProperties方法不會以特定順序返回屬性,例如字母順序或聲明順序。您的代碼不得依賴於返回屬性的順序,因爲順序會有所不同._(取自[MSDN Documentation](https://msdn.microsoft.com/en-us/library/aky14axb.aspx#Anchor_1) ) – KnorxThieus 2017-08-21 20:05:39

+0

比頂部廣泛接受的答案更好,更通用的解決方案 – 2017-09-27 06:25:44

1

我得到這個錯誤在瀏覽器控制檯我尋找它,我發現這個例外是C#和答案也是C#,然後我嘗試看看我的代碼,我發現這裏出現問題:

我有一個ajax post方法,當我發佈數據時有這個錯誤,所以我傳遞的數據將被c#web方法收集,所以當我看到這個模型時,我有兩個屬性具有相同的名稱,所以我刪除了一個,問題和異常解決了。