Вопрос по reflection, system.reflection, c# – Результат отражения GetProperty приводит к появлению «Неоднозначного совпадения» на новом свойстве

27

Как я могу получить свою собственность? В настоящее время происходит ошибка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 Agrawal
@Valamas Пожалуйста, пересмотрите выбранный ответ. Многие придут сюда с условными конструкциями, такими какif (winform.GetType().GetProperty("Items") != null) {..} в этом случае можно просто переключать исключения с помощью Linq ... Lorenz Lo Sauer

Ваш Ответ

7   ответов
31

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));
фантастические вещи! Я упростил это доtype.GetProperties().First(p => p.Name == "MyEntity") Все тесты зеленые! Valamas
Невзирая наFirst или жеSingle, оба будутthrow an exception when no elements are present  начать с!
+1. Хорошие руки для объяснения. Я добавил ссылку RTFM на всякий случай.
Не так хорошо, как следующий ответ, потому что вы вынуждены использовать имя типа. Это не всегда возможно.
0

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

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

12

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

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

Это действительно более универсальное и расширяемое решение.
Очень эффективное решение! Но я боюсь, что порядок свойств не гарантируется: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)
Лучшее и более универсальное решение, чем общепринятый ответ наверху
0

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

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

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

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

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

1

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

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

Похожие вопросы