Извлечение названий свойства отражения, с Intellisense и Compile-Time Checking

Попробуйте

($b/HolidayType/text(),"")[1]

Если в последовательности есть ноль, то ноль просто исчезает.

('A', 'B', 'C', (), 'E') становится ('A', 'B', 'C', 'E')

14
задан GWLlosa 27 April 2009 в 20:43
поделиться

4 ответа

в 3.5, выражение - это один из способов указать имена членов в виде кода; вы можете получить:

public void AddMapping<TObj,TValue>(Control myControl, TObj myObject,
       Expression<Func<TObj, TValue>> mapping) {...}

и затем проанализировать дерево выражений, чтобы получить значение. Немного неэффективно, но не так уж плохо.

Вот пример кода:

    public void AddMapping<TSource, TValue>(
        Control control,
        TSource source,
        Expression<Func<TSource, TValue>> mapping)
    {
        if (mapping.Body.NodeType != ExpressionType.MemberAccess)
        {
            throw new InvalidOperationException();
        }
        MemberExpression me = (MemberExpression)mapping.Body;
        if (me.Expression != mapping.Parameters[0])
        {
            throw new InvalidOperationException();
        }
        string name = me.Member.Name;
        // TODO: do something with "control", "source" and "name",
        // maybe also using "me.Member"
    }

вызывается с:

    AddMapping(myControl, foo, f => f.Bar);
15
ответ дан 1 December 2019 в 12:39
поделиться

Подумайте об использовании лямбды или даже System.Linq.Expressions для этого с одним из:

extern void AddMapping<T,U>(Control control, T target, Func<T,U> mapping);
extern void AddMapping<T,U>(Control control, T target, Expression<Func<T,U>> mapping);

Затем вызовите его с

this.AddMapping(this.myControl, myObject, (x => x.PropertyName));

Используйте аргумент Expression, если вам нужно разбирать абстрактное синтаксическое дерево во время выполнения, выполнять рефлексивные вещи, такие как получение имени свойства в виде строки; в качестве альтернативы, пусть делегат выполнит работу по отбору необходимых вам данных.

2
ответ дан 1 December 2019 в 12:39
поделиться

Вы действительно не должны передавать строковые литералы в качестве имен свойств. Вместо этого вы должны использовать YourClass.PROPERTY_NAME_FOO .

Вы должны объявить эти строки как константы в вашем классе.

public const String PROPERTY_NAME_FOO = "any string, it really doesn't matter";
public const String PROPERTY_NAME_BAR = "some other name, it really doesn't matter";

Или вам вообще не нужно беспокоиться о строках, просто имена свойств:

public const int PROPERTY_NAME_FOO = 0;
public const int PROPERTY_NAME_BAR = 1; //values don't matter, as long as they are unique

Это предотвратит попадание строк, которые не ссылаются на допустимое свойство, в вызовы функций.

Intelisense сможет показывать вам имена свойств из вашего класса в качестве подсказок для автозаполнения.

1
ответ дан 1 December 2019 в 12:39
поделиться
1
ответ дан 1 December 2019 в 12:39
поделиться
Другие вопросы по тегам:

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