web-dev-qa-db-ja.com

GetPropertyリフレクションの結果、新しいプロパティで「あいまいな一致が見つかりました」

どうすれば財産を取得できますか?現在、Ambiguous match foundのエラーが発生しています。コードのコメント行を参照してください。

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

Type.GetProperty

AmbiguousMatchExceptionが発生する状況...

...派生型は、新しい修飾子を使用して、同じ名前の継承されたプロパティを隠すプロパティを宣言します

以下を実行する場合

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

2つのPropertyInfoオブジェクトが返されることがわかります。 1つはMyBaseEntity用で、もう1つはMyDerivedEntity用です。そのため、Ambiguous match foundエラーが表示されます。

次のようにPropertyInfoMyDerivedEntityを取得できます。

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

プロパティの場合:

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-指定された型の階層のレベルで宣言されたメンバーのみを考慮するように指定します。継承されたメンバーは考慮されません。

25
AlphaOmega

newMyDerivedEntity宣言が原因であいまいさが発生します。これを克服するには、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();

これにより、派生型が存在する場合はプロパティを取得し、存在しない場合はベースを取得します。これは必要に応じて簡単にフリップフロップできます。

13
Chad Kuehn

Kevinはすでに問題を指摘しましたが、複雑なステートメントやLINQは必要ありません。

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

私はそれを検索するブラウザコンソールでこのエラーを取得しましたが、この例外はc#用であり、答えはc#用でもあることがわかりました。その後、コードを見て、問題が発生する場所を見つけました:

私はajax postメソッドを持っていますが、データを投稿するとこのエラーが発生したため、渡したデータはc#webメソッドによって収集されます。そのモデルを見ると同じ名前の2つのプロパティがあるので、1つと問題と例外を削除します解決しました。

1
Saurabh Solanki

私にとっては、VB.Netで、JSオブジェクトを<WebMethod()>関数に渡すときに、この説明的なエラーが発生しました。

私のオブジェクトは、他のエンティティへの参照を含むEFエンティティで構成されていました。これらの参照プロパティを何も設定しないと、これは解決しました。なぜこれがJSに送信するためにシリアライズするときに循環参照を引き起こさなかったのか分かりませんが、それはあります。

0
DavidScherer

LocationKeyオブジェクトのMsgPackシリアル化でこの問題が発生していました。 LocationKeyクラスで定義した演算子になりました。これらの演算子の両方を定義すると、DefaultContext.GetSerializer(obj.GetType());がシリアライズしようとしたときにAmbiguous Match Foundをスローしました。オペレーターのセットを削除すると、問題はなくなりました。

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