BindingFlags.IgnoreCase не работает для Type.GetProperty ()?

183

Представьте себе следующее

Тип Т имеет поле Компания. При выполнении следующего метода он работает отлично:

Type t = typeof(T);
t.GetProperty("Company")

При следующем вызове я получаю ноль, хотя

Type t = typeof(T);
t.GetProperty("company", BindingFlags.IgnoreCase)

У кого-нибудь есть идея?

Борис Калленс
источник
20
@OregonGhost: это имеет значение?
Леппи
9
Хотя ваш мета-вопрос действителен, он на самом деле не имеет значения. Как и большинство моих вопросов, моей главной причиной является голод знаний;)
Борис Калленс
1
@leppie: Да, это так. Может быть, есть вариант использования для этого, о котором я не знаю, и всегда интересно, почему люди хотят что-то делать.
OregonGhost
21
@OregonGhost: не все языки, нацеленные на .Net, чувствительны к регистру, поэтому вам иногда нужно делать поиск без учета регистра.
Поп Каталин
2
Вариант использования для меня: чтобы я мог сравнивать объекты с MSSQL Compact Entity, не беспокоясь о том, как они вводили поля. (Я сравниваю объект с компактной базой данных, где некоторые поля имеют имена isSomething и IsSomething.) Другими словами, ради лени.
Тейнон

Ответы:

389

Вы перезаписали флаги поиска по умолчанию, если вы указываете новые флаги, вам нужно предоставить всю информацию, чтобы свойство могло быть найдено. Например:BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance

Поп-каталин
источник
7
у любого есть идея, почему это так (просить ради знания;))
Шриваллаб
2
@Shrivallabh BindingFlags.Public | BindingFlags.Instance - это флаги по умолчанию, когда вы указываете только имя свойства
Отабек
1
@Shrivallabh В дополнение к объяснению Отабека Холикова, если бы они сохраняли эти значения по умолчанию и добавляли (ИЛИ) ваши данные BindingFlagsк ним, не было бы никакого способа не использовать значения по умолчанию. Т.е. было бы невозможно исключить Publicсвойства или исключить Instanceсвойства. Они решили, что вы либо берете значения по умолчанию, либо переопределите их, указав именно то, что вам нужно.
xr280xr
36

Вам нужно добавить BindingFlags.Public | BindingFlags.Instance

leppie
источник
2
Вы получаете меньше голосов, но вы были на 2 минуты быстрее - но опять же, в ответе Попа было больше деталей. Я отдаю голоса всем, кто заслуживает! :)
Тони Басалло
10

Спасибо, это действительно помогло мне в крайнем случае сегодня. У меня была сохранена информация аудита, но с неправильным регистром в именах свойств. (Аудит встроен в слой данных.) В любом случае мне пришлось добавить IgnoreCase в качестве флага привязки, но тогда он все еще не работал, пока мой коллега не нашел этот ответ. Полученная функция:

public static void SetProperty(Object R, string propertyName, object value)
{
    Type type = R.GetType();
    object result;
    result = type.InvokeMember(
        propertyName, 
        BindingFlags.SetProperty | 
        BindingFlags.IgnoreCase | 
        BindingFlags.Public | 
        BindingFlags.Instance, 
        null, 
        R, 
        new object[] { value });
}

Это часть класса, который я называю DotMagic.

Джош Уорнер-Берк
источник