2012-07-12 13 views
21

Jak mogę dostać swoją nieruchomość? Aktualnie pojawia się błąd Ambiguous match found, patrz wiersz komentarza w kodzie.Odwzorowanie GetProperty skutkuje "Niejednoznacznym dopasowaniem znalezionym" na nowej nieruchomości

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

Błąd czasu wykonania lub błąd czasu kompilacji? –

+1

@Valamas Prosimy o ponowne rozpatrzenie wybranej odpowiedzi. Wielu przyjdzie tutaj z konstruktami warunkowymi, takimi jak 'if (winform.GetType(). GetProperty (" Items ")! = Null) {..}' w takim przypadku po prostu przełącza się Wyjątki przy użyciu Linq ... –

Odpowiedz

24

Type.GetProperty

Sytuacje, w których występuje AmbiguousMatchException ...

... Typ pochodzi deklaruje właściwość, która ukrywa odziedziczoną nieruchomość o tej samej nazwie, przy użyciu nowego modyfikatora

Jeśli uruchomisz następujące:

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

zobaczysz, że zwrócone są dwa obiekty: PropertyInfo. Jeden dla MyBaseEntity i jeden dla MyDerivedEntity. Właśnie dlatego otrzymujesz błąd niejednoznacznego znalezienia błędu.

można uzyskać PropertyInfo dla MyDerivedEntity tak:

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

+1. Dobre ręce na wyjaśnienia. Na wszelki wypadek dodałem link RTFM. –

+0

fantastyczne rzeczy! Uprościłem to do 'type.GetProperties(). First (p => p.Name ==" MyEntity ")' Wszystkie testy są zielone! –

+1

Bez względu na "Pierwszy" lub "Pojedynczy", oba będą ** zgłaszać wyjątek, gdy nie ma żadnych elementów ** na początek! –

5

Kevin już zwrócił uwagę na problem, ale nie trzeba złożonych oświadczeń lub LINQ do tego:

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

Dla właściwość:

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

Dla metody:

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

BindingFlags .DeclaredOnly - Określa, że ​​należy uwzględnić tylko członków zadeklarowanych na poziomie hierarchii dostarczonego typu. Odziedziczeni członkowie nie są brani pod uwagę.

0

Wystąpił ten problem podczas serializacji MsgPack mojego obiektu LocationKey. W końcu byłem operatorem, który zdefiniowałem w mojej klasie LocationKey. Posiadanie obu tych operatorów spowodowało, że DefaultContext.GetSerializer(obj.GetType()); rzucił niejednoznaczne dopasowanie znalezione podczas próby serializowania. Usunięcie jednego zestawu operatorów spowodowało, że problem zniknął.

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

Niejednoznaczność występuje z powodu deklaracji w MyDerivedEntitynew. Aby temu zaradzić można użyć 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(); 

To będzie chwycić właściwość wyjście typu pochodzącego jeśli istnieje, w przeciwnym razie podstawy. W razie potrzeby można to łatwo przerzucić na flip-flop.

+1

To naprawdę bardziej uniwersalne i rozszerzalne rozwiązanie. – it3xl

+1

Bardzo wydajne rozwiązanie! Obawiam się jednak, że kolejność właściwości nie jest gwarantowana: _ Metoda 'M: System.Type.GetProperties' nie zwraca właściwości w określonej kolejności, na przykład w kolejności alfabetycznej lub deklaracji. Twój kod nie może zależeć od kolejności, w której właściwości są zwracane, ponieważ to zamówienie jest różne._ (pobrane z [Dokumentacja MSDN] (https://msdn.microsoft.com/en-us/library/aky14axb.aspx#Anchor_1)) – KnorxThieus

+0

Lepsze i bardziej uniwersalne rozwiązanie niż powszechnie akceptowana odpowiedź na górze –

1

mam tego błędu w konsoli przeglądarki go szukać i znalazłem ten wyjątek jest dla C# i odpowiedzi jest również dla C#, a następnie staram się patrzeć na mojego kodu i uważam, że tam gdzie pojawia się problem:

Mam metodę ajax ajax i kiedy wysyłam dane dostaję ten błąd, więc dane, które przekazałem, zostaną zebrane metodą C# web, więc gdy zobaczę ten model, mam 2 właściwości o tej samej nazwie, więc usunąłem jeden i problem i wyjątek został rozwiązany.

Powiązane problemy