2013-07-26 156 views
1

随着数据绑定对象来控制和网格我讨厌属性名称怎么会魔法字符串,所以我创建了一个非常简单的方法如下:获取子属性名称强类型

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

这让我使用代码,如:

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

这东西修改后的版本,我可能已经在这里找到了计算器:

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

伟大的东西,只是我会用像这样的公共静态字符串GetPropertyName (此表达式> propertyExpression)替换TProperty,在这种情况下,您不需要指定使用扩展时的属性类型这并不影响其他代码。 – Giedrius

+0

@Giedrius,类型是自动推断的(假设你使用MemberExpression)。因此你不需要指定类型。这编译:'string propertyName = someMemberExpression.GetPropertyName();' – lightbricko