Результаты отражения 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
}
Ответы
Ответ 1
Type.GetProperty
Ситуации, в которых происходит событие AmbiguousMatchException...
... производный тип объявляет свойство, которое скрывает унаследованное свойство с тем же именем, используя новый модификатор
Если вы запустите следующий
var properties = myDE.GetType().GetProperties().Where(p => p.Name == "MyEntity");
вы увидите, что возвращаются два объекта PropertyInfo
. Один для MyBaseEntity
и один для MyDerivedEntity
. Вот почему вы получаете обнаруженную неоднозначную ошибку.
Вы можете получить PropertyInfo
для MyDerivedEntity
следующим образом:
PropertyInfo propInfoSrcObj = myDE.GetType().GetProperties().Single(p =>
p.Name == "MyEntity" && p.PropertyType == typeof(MyDerivedEntity));
Ответ 2
Для свойства:
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 - указывает, что должны учитываться только члены, объявленные на уровне поставляемой иерархии типов. Унаследованные члены не учитываются.
Ответ 3
Неопределенность возникает из-за объявления 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();
Это будет захватывать свойство из производного типа, если оно существует, иначе база. Это может быть легко сфотографировано при необходимости.
Ответ 4
Кевин уже указал на проблему, но вам не нужны сложные операторы или LINQ для этого:
PropertyInfo propInfoSrcObj = myDE.GetType().
GetProperty("MyEntity", typeof(MyDerivedEntity));
Ответ 5
У меня возникла проблема с сериализацией MsgPack моего объекта LocationKey. Закончились те операторы, которые я определил в своем классе LocationKey. Если оба этих оператора определили, то вызвали DefaultContext.GetSerializer(obj.GetType());
, чтобы бросить неоднозначное совпадение, найденное при попытке сериализации. Удаление одного набора операторов заставило проблему уйти.
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;
}