web-dev-qa-db-fra.com

La réflexion GetProperty aboutit à une "correspondance ambiguë" sur la nouvelle propriété

Comment puis-je obtenir ma propriété? Actuellement, une erreur de Ambiguous match found se produit, voir la ligne de commentaire dans le 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

Situations dans lesquelles AmbiguousMatchException se produit ...

... type dérivé déclare une propriété qui masque une propriété héritée du même nom, en utilisant le modificateur new

Si vous exécutez ce qui suit

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

vous verrez que deux objets PropertyInfo sont retournés. Un pour MyBaseEntity et un pour MyDerivedEntity. C’est pourquoi vous recevez la correspondance Ambiguous found error.

Vous pouvez obtenir la PropertyInfo pour MyDerivedEntity comme ceci:

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

Pour la propriété:

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

Pour la méthode:

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

BindingFlags . DeclaredOnly - Spécifie que seuls les membres déclarés au niveau de la hiérarchie du type fourni doivent être pris en compte. Les membres hérités ne sont pas pris en compte.

20
AlphaOmega

L'ambiguïté est due à la déclaration new dans MyDerivedEntity. Pour surmonter cela, vous pouvez utiliser 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();

Cela extraira la propriété du type dérivé s'il existe, sinon la base. Cela peut facilement être inversé si nécessaire.

11
Chad Kuehn

Kevin a déjà souligné le problème, mais vous n'avez pas besoin de déclarations complexes, ni de LINQ pour cela:

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

J'ai eu cette erreur dans la console du navigateur. Je l'ai trouvée et j'ai trouvé que cette exception concernait c # et que la réponse concernait également c #, puis j'essayais de consulter mon code et je trouvais l'endroit où le problème se produisait: 

J'ai une méthode de publication ajax et lorsque je publie des données, cette erreur est renvoyée. Les données que j'ai transmises sont alors collectées par la méthode Web c #. Ainsi, lorsque je vois ce modèle, j'ai 2 propriétés portant le même nom. s'est résolu. 

1
Saurabh Solanki

Pour moi, dans VB.Net, j’ai rencontré cette erreur super descriptive lors du passage d’un objet JS à une fonction <WebMethod()>

Mon objet était composé d'entités EF contenant des références à d'autres entités. La définition de ces propriétés de référence sur rien a résolu ce problème. Aucune idée de la raison pour laquelle cela n'a pas provoqué l'envoi d'une référence cyclique lors de la sérialisation à JS, mais voilà.

0
DavidScherer

J'avais ce problème avec la sérialisation MsgPack de mon objet LocationKey. En fin de compte être les opérateurs que j'avais définis dans ma classe LocationKey. La définition de ces deux opérateurs a provoqué le déclenchement par DefaultContext.GetSerializer(obj.GetType()); de la correspondance ambiguë lors de la tentative de sérialisation. La suppression d’un ensemble d’opérateurs a permis de résoudre le problème.

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