2011-01-11 2 views
21

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

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

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

где property1 является свойством типа OBJECTTYPE.

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

ответ

54

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

// 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); 

Update: фиксированной GetPropertyName<TObject>(Expression<Func<TObject, object>> exp) для свойств возвращающимся типов значений.

+0

Есть ли шанс заставить его работать без создания экземпляра сначала и без пустых скобок? Просто (x => x.Prop1) – user137348

+0

Добавлена ​​перегрузка для этого случая (код такой же, хотя идея уже выражена в ответе Дарина). – max

+0

есть одна небольшая проблема, я должен указать тип свойства (int, string ..) Может ли это обрабатываться? – user137348

7
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; 
    } 
} 
Смежные вопросы