it-swarm.com.de

GetProperty-Reflektion führt zu "mehrdeutiger Übereinstimmung gefunden" bei neuer Eigenschaft

Wie kann ich mein Eigentum bekommen? Momentan tritt ein Fehler von Ambiguous match found auf, siehe Kommentarzeile im Code.

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
}
26
Valamas

Type.GetProperty

Situationen, in denen AmbiguousMatchException auftritt ...

... Der abgeleitete Typ deklariert eine Eigenschaft, die eine geerbte Eigenschaft mit demselben Namen mit dem neuen Modifizierer verbirgt

Wenn du folgendes ausführst

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

sie werden sehen, dass zwei PropertyInfo-Objekte zurückgegeben werden. Eine für MyBaseEntity und eine für MyDerivedEntity. Deshalb erhalten Sie den Fehler Ambiguous match found.

Sie können die PropertyInfo für MyDerivedEntity folgendermaßen erhalten:

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

Für Eigenschaft:

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

Für die Methode:

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

BindingFlags . DeclaredOnly - Gibt an, dass nur Member berücksichtigt werden sollen, die auf der Ebene der angegebenen Hierarchie des Typs deklariert sind. Vererbte Mitglieder werden nicht berücksichtigt.

20
AlphaOmega

Die Mehrdeutigkeit tritt aufgrund der new-Deklaration in MyDerivedEntity auf. Um dies zu überwinden, können Sie LINQ verwenden:

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

Dadurch wird die Eigenschaft aus dem abgeleiteten Typ herausgezogen, falls vorhanden, andernfalls die Basis. Dies kann bei Bedarf leicht umgedreht werden.

11
Chad Kuehn

Kevin hat bereits auf das Problem hingewiesen, aber Sie brauchen dafür keine komplexen Aussagen oder LINQ:

PropertyInfo propInfoSrcObj = myDE.GetType().
    GetProperty("MyEntity", typeof(MyDerivedEntity));
7
Lorenz Lo Sauer

Ich habe diesen Fehler in der Browserkonsole gefunden. Ich suche danach und habe festgestellt, dass diese Ausnahme für c # gilt und die Antwort auch für c # gilt. Dann versuche ich, meinen Code zu überprüfen, und ich habe herausgefunden, wo das Problem auftritt: 

Ich habe eine Ajax-Post-Methode, und wenn ich die Daten poste, erhielt ich diesen Fehler. Die von mir übergebenen Daten werden von der C # Web-Methode erfasst. Wenn ich also dieses Modell sehe, habe ich 2 Eigenschaften mit dem gleichen Namen, also entferne ich eine, ein Problem und eine Ausnahme wurde gelöst. 

1
Saurabh Solanki

Bei mir in VB.Net ist dieser super beschreibende Fehler aufgetreten, wenn ein JS-Objekt an eine <WebMethod()>-Funktion übergeben wurde. 

Mein Objekt bestand aus EF-Entitäten, die Verweise auf andere Entitäten enthielten. Wenn Sie diese Referenzeigenschaften auf nichts setzen, wurde dies behoben. Keine Ahnung, warum dies beim Serialisieren keine zyklische Referenz an den JS gesendet hat, aber da ist es.

0
DavidScherer

Ich hatte dieses Problem mit der MsgPack-Serialisierung meines LocationKey-Objekts. Am Ende waren es die Operatoren, die ich in meiner LocationKey-Klasse definiert hatte. Wenn diese beiden Operatoren definiert wurden, hat DefaultContext.GetSerializer(obj.GetType()); beim Versuch, die Serialisierung auszuführen, eine mehrdeutige Übereinstimmung gefunden. Durch das Entfernen eines Operatorsatzes wurde das Problem behoben.

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;
}
0
odyth