Подтвердить что ты не робот

Reflection - получить имя свойства

Я хотел бы передать имена свойств функции без использования магических строк.

Что-то вроде:

Get<ObjectType>(x=>x.Property1);

где Property1 является свойством типа ObjectType.

Как выглядит реализация метода?

4b9b3361

Ответ 1

Это может быть достигнуто с помощью выражений:

// requires object instance, but you can skip specifying T
static string GetPropertyName<T>(Expression<Func<T>> exp)
{
    return (((MemberExpression)(exp.Body)).Member).Name;
}

// requires explicit specification of both object type and property type
static string GetPropertyName<TObject, TResult>(Expression<Func<TObject, TResult>> exp)
{
    // extract property name
    return (((MemberExpression)(exp.Body)).Member).Name;
}

// requires explicit specification of object type
static string GetPropertyName<TObject>(Expression<Func<TObject, object>> exp)
{
    var body = exp.Body;
    var convertExpression = body as UnaryExpression;
    if(convertExpression != null)
    {
        if(convertExpression.NodeType != ExpressionType.Convert)
        {
            throw new ArgumentException("Invalid property expression.", "exp");
        }
        body = convertExpression.Operand;
    }
    return ((MemberExpression)body).Member.Name;
}

Использование:

var x = new ObjectType();
// note that in this case we don't need to specify types of x and Property1
var propName1 = GetPropertyName(() => x.Property1);
// assumes Property2 is an int property
var propName2 = GetPropertyName<ObjectType, int>(y => y.Property2);
// requires only object type
var propName3 = GetPropertyName<ObjectType>(y => y.Property3);

Обновление: исправлено GetPropertyName<TObject>(Expression<Func<TObject, object>> exp) для свойств, возвращающих типы значений.

Ответ 2

class Foo
{
    public string Bar { get; set; }
}

class Program
{
    static void Main()
    {
        var result = Get<Foo, string>(x => x.Bar);
        Console.WriteLine(result);
    }

    static string Get<T, TResult>(Expression<Func<T, TResult>> expression)
    {
        var me = expression.Body as MemberExpression;
        if (me != null)
        {
            return me.Member.Name;
        }
        return null;
    }
}