Результат отражения 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
}
 Nikhil Agrawal12 июл. 2012 г., 03:07
Ошибка времени выполнения или ошибка времени компиляции?
 Lorenz Lo Sauer27 сент. 2013 г., 23:01
@Valamas Пожалуйста, пересмотрите выбранный ответ. Многие придут сюда с условными конструкциями, такими какif (winform.GetType().GetProperty("Items") != null) {..} в этом случае можно просто переключать исключения с помощью Linq ...

Ответы на вопрос(7)

У меня была эта проблема с сериализацией 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;
}
Решение Вопроса

Type.GetProperty

Situations in which AmbiguousMatchException occurs ...

...derived type declares a property that hides an inherited property with the same name, by using the new modifier

Если вы запустите следующее

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

вы увидите, что дваPropertyInfo объекты возвращаются. Один дляMyBaseEntity и один дляMyDerivedEntity, Вот почему вы получаетеAmbiguous match found ошибка.

Вы можете получитьPropertyInfo заMyDerivedEntity как это:

PropertyInfo propInfoSrcObj = myDE.GetType().GetProperties().Single(p => 
    p.Name == "MyEntity" && p.PropertyType == typeof(MyDerivedEntity));
 12 авг. 2014 г., 15:10
Не так хорошо, как следующий ответ, потому что вы вынуждены использовать имя типа. Это не всегда возможно.
 Valamas12 июл. 2012 г., 03:36
фантастические вещи! Я упростил это доtype.GetProperties().First(p => p.Name == "MyEntity") Все тесты зеленые!
 12 июл. 2012 г., 03:31
+1. Хорошие руки для объяснения. Я добавил ссылку RTFM на всякий случай.
 27 сент. 2013 г., 22:51
Невзирая наFirst или жеSingle, оба будутthrow an exception when no elements are present  начать с!

Для меня в VB.Net я столкнулся с этой супер описательной ошибкой при передаче объекта JS в<WebMethod()> функция.

Мой объект был составлен из сущностей EF, которые содержали ссылки на другие сущности. Установка этих ссылочных свойств в ничто не решила это. Не знаю, почему это не вызывало циклическую ссылку при сериализации для отправки в JS, но это так.

Неопределенность возникает из-за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();

Это приведет к извлечению свойства из производного типа, если оно существует, в противном случае - к основанию. Это может быть легко перевернуто в случае необходимости.

 31 мая 2016 г., 11:59
Это действительно более универсальное и расширяемое решение.
 21 авг. 2017 г., 22:05
Очень эффективное решение! Но я боюсь, что порядок свойств не гарантируется:The M:System.Type.GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies. (Взято изMSDN Documentation)
 27 сент. 2017 г., 08:25
Лучшее и более универсальное решение, чем общепринятый ответ наверху

Для недвижимости:

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 - указывает, что должны рассматриваться только члены, объявленные на уровне иерархии предоставленного типа. Унаследованные члены не рассматриваются.

Я получил эту ошибку в консоли браузера, которую я ищу, и обнаружил, что это исключение для c #, и ответ также для c #, затем я пытаюсь посмотреть на свой код, и я нашел, где возникает проблема:

У меня есть метод поста ajax, и когда я публикую данные, получена эта ошибка, поэтому данные, которые я передал, будут собираться с помощью веб-метода c #, поэтому, когда я вижу эту модель, у меня есть 2 свойства с одинаковым именем, поэтому я удаляю одно, проблему и исключение был решен.

Кевин уже указал на проблему, но вам не нужны сложные заявления или LINQ для этого:

PropertyInfo propInfoSrcObj = myDE.GetType().
    GetProperty("MyEntity", typeof(MyDerivedEntity));

Ваш ответ на вопрос