Propertyinfo не получает свойство строки

У меня проблема с PropertyInfo. Мой код здесь

Type type = typeof(T);
PropertyInfo propertyInfo = type.GetProperty(filterDescriptor.Member);
if (propertyInfo != null && propertyInfo.PropertyType.FullName.ToLower() == "system.string")
{
    isMemberStringType = true;
    filterDescriptor.Value = filterDescriptor.Value ?? string.Empty;
}

Проблема в том, что propertyInfo получает NULL, если filterDescriptor.Member содержит значение, подобное

abc.key
abc.Name

Но когда он содержит Just Key and Name, он работает, он получает system.string и выполняет if. Как мне это преодолеть. Помогите.


person EHS    schedule 04.12.2013    source источник
comment
Без знания того, что здесь abc, нет правильного ответа. имя класса? имя интерфейса? связанное имя свойства?   -  person nawfal    schedule 13.12.2013


Ответы (2)


В документации MSDN очень ясно сказано:

Параметры
имя
Тип: System.String

Строка, содержащая имя общедоступного свойства, которое необходимо получить.

Ни один класс не может содержать свойство с точкой (.) в имени.
Чего вы пытаетесь достичь (я думаю), так это проверить дочернее свойство (например, ваш класс имеет свойство с именем abc, а класс этого свойства имеет собственное свойство с именем key ).

Для этого вам нужно использовать рекурсию.

public bool HasPropertyInPath(
    Type checkedType,
    string propertyPath,
    Type propertyType)
{
    int dotIndex = propertyPath.IndexOf('.');
    if (dotIndex != -1)
    {
        PropertyInfo topPropertyInfo
            = checkedType.GetProperty(propertyPath.Substring(0, dotIndex));

        if (topPropertyInfo == null)
        {
            return false;
        }

        return HasPropertyInPath(
            topPropertyInfo.PropertyType,
            propertyPath.Substring(dotIndex + 1),
            propertyType);
    }

    PropertyInfo propertyInfo = checkedType.GetProperty(propertyPath);

    return (propertyInfo != null && propertyInfo.PropertyType == propertyType);
}

Затем вы можете использовать его следующим образом:

if (HasPropertyInPath(typeof(T), filterDescriptor.Member, typeof(string))
{
    isMemberStringType = true;
    filterDescriptor.Value = filterDescriptor.Value ?? string.Empty;
}


Вышеприведенный код не тестировался, но следует проверять дочерние свойства.

person mozgow    schedule 04.12.2013
comment
Свойства класса действительно могут иметь . в своих именах, например, явно реализованные свойства. - person nawfal; 13.12.2013

Это невозможно при простом вызове GetProperty, потому что он работает только для текущего уровня объекта. Что вы хотите сделать, так это пройти через вложенные свойства. И вы должны помнить о разном подходе к коллекциям (потому что вы хотите видеть свойства их элементов, а не свойства самой коллекции):

static System.Reflection.PropertyInfo GetProperty(Type type, string propertyPath)
{
    System.Reflection.PropertyInfo result = null;
    string[] pathSteps = propertyPath.Split('.');
    Type currentType = type;
    for (int i = 0; i < pathSteps.Length; ++i)
    {
        string currentPathStep = pathSteps[i];
        result = currentType.GetProperty(currentPathStep);
        if (result.PropertyType.IsArray)
        {
            currentType = result.PropertyType.GetElementType();
        }
        else
        {
            currentType = result.PropertyType;
        }
    }
    return result;
}

а затем вы можете «запросить» объекты с «путями»:

PropertyInfo pi = GetProperty(c1.GetType(), "ArrayField1.Char");
PropertyInfo pi2 = GetProperty(c2.GetType(), "Color");

Дополнительные сведения см. в разделе этот ответ.

person Konrad Kokosa    schedule 13.12.2013