Получить имя и тип свойства с помощью лямбда-выражения - PullRequest
35 голосов
/ 08 ноября 2008

Я пытаюсь написать функцию, которая будет извлекать имя свойства и тип, используя синтаксис, как показано ниже:

private class SomeClass
{
    Public string Col1;
}

PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>();
propertyMapper.MapProperty(x => x.Col1)

Есть ли способ передать свойство в функцию без каких-либо существенных изменений в этом синтаксисе?

Я хотел бы получить имя свойства и тип свойства.

Так что в приведенном ниже примере я бы хотел получить

Name = "Col1" и Type = "System.String"

Может кто-нибудь помочь?

Ответы [ 4 ]

60 голосов
/ 08 ноября 2008

Вот достаточно примера использования выражений , чтобы получить имя свойства или поля для начала работы:

public static MemberInfo GetMemberInfo<T, U>(Expression<Func<T, U>> expression)
{
    var member = expression.Body as MemberExpression;
    if (member != null)
        return member.Member;

    throw new ArgumentException("Expression is not a member access", "expression");
}

Телефонный код будет выглядеть так:

public class Program
{
    public string Name
    {
        get { return "My Program"; }
    }

    static void Main()
    {
        MemberInfo member = ReflectionUtility.GetMemberInfo((Program p) => p.Name);
        Console.WriteLine(member.Name);
    }
}

Тем не менее, предостережение: простая оценка (Program p) => p.Name на самом деле включает в себя довольно много работы (и может занимать измеримое количество времени). Попробуйте кэшировать результат, а не вызывать метод часто.

3 голосов
/ 22 июня 2016

Это легко сделать в C # 6. Для получения имени свойства используйте оператор nameof.

nameof(User.UserId)

и для получения типа свойства используйте оператор typeof.

typeof(User.UserId)
3 голосов
/ 08 апреля 2016

Я просто подумал, что я бы положил это здесь, чтобы опираться на предыдущий подход.

public static class Helpers
{
    public static string PropertyName<T>(Expression<Func<T>> expression)
    {
        var member = expression.Body as MemberExpression;
        if (member != null && member.Member is PropertyInfo)
            return member.Member.Name;

        throw new ArgumentException("Expression is not a Property", "expression");
    }
}

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

Helpers.PropertyName(() => TestModel.TestProperty);

Я также должен отметить, что с VS 2015 и C # 6.0 вы можете просто использовать nameof.

https://msdn.microsoft.com/en-us/library/dn986596.aspx

3 голосов
/ 05 ноября 2014

Я нашел это очень полезным.

public class PropertyMapper<T>
{
    public virtual PropertyInfo PropertyInfo<U>(Expression<Func<T, U>> expression)
    {
        var member = expression.Body as MemberExpression;
        if (member != null && member.Member is PropertyInfo)
            return member.Member as PropertyInfo;

        throw new ArgumentException("Expression is not a Property", "expression");
    }

    public virtual string PropertyName<U>(Expression<Func<T, U>> expression)
    {
        return PropertyInfo<U>(expression).Name;
    }

    public virtual Type PropertyType<U>(Expression<Func<T, U>> expression)
    {
        return PropertyInfo<U>(expression).PropertyType;
    }
}

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

PropertyMapper<SomeClass> propertyMapper = new PropertyMapper<SomeClass>();
string name = propertyMapper.PropertyName(x => x.Col1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...