GetProperty反射导致新属性上出现"模糊匹配"

Val*_*mas 30 c# reflection system.reflection

我如何获得我的财产?目前发生错误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
}
Run Code Online (Sandbox Code Playgroud)

Kev*_*mey 35

Type.GetProperty

出现AmbiguousMatchException的情况......

...派生类型声明一个属性,该属性使用new修饰符隐藏具有相同名称的继承属性

如果您运行以下

var properties = myDE.GetType().GetProperties().Where(p => p.Name == "MyEntity");
Run Code Online (Sandbox Code Playgroud)

你会看到PropertyInfo返回两个对象.一个为MyBaseEntity一个为一个MyDerivedEntity.这就是您收到Ambiguous match found错误的原因.

你可以得到PropertyInfoMyDerivedEntity是这样的:

PropertyInfo propInfoSrcObj = myDE.GetType().GetProperties().Single(p => 
    p.Name == "MyEntity" && p.PropertyType == typeof(MyDerivedEntity));
Run Code Online (Sandbox Code Playgroud)

  • +1.善于解释.为了以防万一,我添加了RTFM链接. (2认同)
  • 不如下一个答案那么好,因为你被迫使用Type的名字.并非总是可行. (2认同)
  • 我会匹配 DeclaringType 而不是 PropertyType,这样您就可以指定要匹配属性的类,因为在某些情况下它们可能具有相同的类型。 (2认同)

Alp*_*ega 25

对于财产:

MemberInfo property = myDE.GetProperty(
    "MyEntity",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
Run Code Online (Sandbox Code Playgroud)

方法:

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

BindingFlags .DeclaredOnly - 指定只应考虑在提供的类型的层次结构级别声明的成员.不考虑继承的成员.

  • 我不明白为什么这不是最受欢迎的答案,它是唯一安全的解决方案,因为第一个答案尝试匹配返回类型而不是使用那个简单的标志。 (3认同)

Cha*_*ehn 13

由于new声明中出现歧义MyDerivedEntity.为了克服这个问题,您可以使用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();
Run Code Online (Sandbox Code Playgroud)

这将从派生类型中获取属性(如果存在),否则为基础.如果需要,这可以很容易地翻转.

  • 非常有效的解决方案!但是我担心不能保证属性的顺序:_M:System.Type.GetProperties方法不会以特定顺序返回属性,例如字母顺序或声明顺序。您的代码不得依赖于属性的返回顺序,因为该顺序会有所不同。_(摘自[MSDN文档](https://msdn.microsoft.com/zh-cn/library/aky14axb.aspx#Anchor_1) ) (2认同)

Lor*_*uer 8

Kevin已经指出了这个问题,但你不需要复杂的语句或LINQ:

PropertyInfo propInfoSrcObj = myDE.GetType().
    GetProperty("MyEntity", typeof(MyDerivedEntity));
Run Code Online (Sandbox Code Playgroud)