2013-07-26 5 views
1

С Databinding объектов к элементам управления и сетках я ненавистных как имена свойств были бы волшебные строки, так что я создал очень простой метод следующим образом:Попадая имена к югу собственности сильно типизированных

public static string GetPropertyName<PropertyType>(Expression<Func<T, PropertyType>> expressionForProperty) 
    { 
     MemberExpression expression = expressionForProperty.Body as MemberExpression; 
     return expression.Member.Name; 
    } 

Это позволяет мне использовать такой код as:

Product.GetPropertyName(m => m.Name) 

для возврата «Имя».

Это прекрасно работает для базовых объектов. Однако, если я изменю вызов метода:

Product.GetPropertyName(m => m.ProductCategory.Name) 

Это также возвращает «Имя». Но для того, чтобы привязка данных работала, мне понадобится вернуть «ProductCategory.Name». Есть ли способ, которым я могу это сделать, изменив метод «GetPropertyName»?

Возможный обходной путь будет сделать это:

string test = Product.GetPropertyName(p => p.ProductCategory) + "." + ProductCategory.GetPropertyName(pc => pc.Name) 

Однако, это не изящное решение.

+0

возможный дубликат [Получить недвижимость , как строку, из выражения >] (http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty) – nawfal

ответ

0

я придумал, после чего, кажется, работает:

public static string GetComplexPropertyName<PropertyType>(Expression<Func<T, PropertyType>> expressionForProperty) 
{ 
    // get the expression body 
    Expression expressionBody = expressionForProperty.Body as MemberExpression; 

    string expressionAsString = null; 

    // all properties bar the root property will be "convert" 
    switch (expressionBody.NodeType) 
    { 
     case ExpressionType.Convert: 
     case ExpressionType.ConvertChecked: 

      UnaryExpression unaryExpression = expressionBody as UnaryExpression; 

      if (unaryExpression != null) 
      { 
       expressionAsString = unaryExpression.Operand.ToString(); 
      } 

      break; 
     default: 
      expressionAsString = expressionBody.ToString(); 
      break; 
    } 

    // makes ure we have got an expression 
    if (!String.IsNullOrWhiteSpace(expressionAsString)) 
    { 
     // we want to get rid of the first operand as it will be the root type, so get the first occurence of "." 
     int positionOfFirstDot = expressionAsString.IndexOf('.'); 

     if (positionOfFirstDot != -1) 
     { 
      return expressionAsString.Substring(positionOfFirstDot + 1, expressionAsString.Length - 1 - positionOfFirstDot); 
     } 
    } 

    return string.Empty; 
} 
3

Это модифицированная версия что-то я мог бы найти здесь, на StackOverflow:

public static class GetPropertyNameExtension 
{ 
    public static string GetPropertyName<TArg, TProperty>(this Expression<Func<TArg, TProperty>> propertyExpression) 
    { 
     return propertyExpression.Body.GetMemberExpression().GetPropertyName(); 
    } 

    public static string GetPropertyName<TProperty>(this Expression<Func<TProperty>> propertyExpression) 
    { 
     return propertyExpression.Body.GetMemberExpression().GetPropertyName(); 
    } 

    public static string GetPropertyName(this MemberExpression memberExpression) 
    { 
     if (memberExpression == null) 
     { 
      return null; 
     } 

     if (memberExpression.Member.MemberType != MemberTypes.Property) 
     { 
      return null; 
     } 

     var child = memberExpression.Member.Name; 
     var parent = GetPropertyName(memberExpression.Expression.GetMemberExpression()); 

     return parent == null ? 
      child 
      : parent + "." + child; 
    } 

    public static MemberExpression GetMemberExpression(this Expression expression) 
    { 
     if (expression is MemberExpression) 
      return (MemberExpression)expression; 

     if (expression is UnaryExpression) 
      return (MemberExpression)((UnaryExpression)expression).Operand; 

     return null; 
    } 
} 
+0

Спасибо, я попробую это в понедельник. Через несколько минут после публикации этого я нашел способ сделать это. Я отправлю его, как только вернусь к работе. – eyeballpaul

+0

Отличный материал, просто я заменил бы TProperty таким объектом, как эта 'public static string GetPropertyName (это выражение > propertyExpression)', в этом случае вам не нужно будет указывать тип свойства при использовании расширения и это не влияет на остальную часть кода. – Giedrius

+0

@ Giedrius. Тип автоматически выводится (если вы используете выражение MemberExpression). Следовательно, вам не нужно указывать тип. Это компилирует: 'string propertyName = someMemberExpression.GetPropertyName();' – lightbricko

Смежные вопросы