2016-07-09 165 views
0

基本上我試圖做很簡單的事情,但我無法弄清楚,如何做到這一點。 我試圖從expresion獲得屬性名稱,例如,對於這個表情我希望得到的結果:從數組屬性的表達式獲取屬性名稱

  • PropertyName(e => e.Easy) = 「易」
  • PropertyName(e => e.Not.So.Easy) = 「Not.So.Easy」
  • PropertyName(e => e.ImLost[i])我在變量for循環=「ImLost [0]」,「ImLost [1]」,...

對於前兩個它相對容易,但對於第三個我迷路了,但我認爲我不能成爲第一個想要實現同樣目標的人。你有什麼建議或想法? PropertyName方法的簽名如下static string PropertyName<T, TProp>(Expression<Func<T, TProp>> expr) where T : class

+0

你如何目前正在實施'PropertyName'?你能顯示你的代碼嗎? –

回答

0

下將處理所有三種情況:

using System; 
using System.Collections; 
using System.Linq.Expressions; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Reflection; 

namespace PropertyNameFromExpression 
{ 
    [TestClass] 
    public class PropertyNameTests 
    { 
     [TestMethod] 
     public void TestCanGetEasyExpression() 
     { 
      string propertyName = PropertyName<Source>(e => e.Easy); 
      Assert.AreEqual("Easy", propertyName); 
     } 
     [TestMethod] 
     public void TestCanGetNotSoEasyExpression() 
     { 
      string propertyName = PropertyName<Source>(e => e.Not.So.Easy); 
      Assert.AreEqual("Not.So.Easy", propertyName); 
     } 
     [TestMethod] 
     public void TestCanGetArrayExpressionWithConstantIndex() 
     { 
      string propertyName = PropertyName<Difficult>(e => e.ImLost[3]); 
      Assert.AreEqual("ImLost["+3+"]", propertyName); 
     } 
     [TestMethod] 
     public void TestCanGetArrayExpressionWithVariableIndex() 
     { 
      int i = 3; 
      string propertyName = PropertyName<Difficult>(e => e.ImLost[i]); 
      Assert.AreEqual("ImLost[" + i + "]", propertyName); 
     } 

     public string PropertyName<TSource>(Expression<Func<TSource, int>> expression) 
     { 
      return PropertyName(expression.Body); 
     } 

     private string PropertyName(Expression expression) 
     { 
      if (expression is BinaryExpression) 
      { 
       return PropertyName(expression as BinaryExpression); 
      } 
      if (expression is ConstantExpression) 
      { 
       return (expression as ConstantExpression).Value.ToString(); 
      } 
      MemberExpression memberExpression = expression as MemberExpression; 
      if (memberExpression.Expression is MemberExpression) 
      { 
       return PropertyName(memberExpression.Expression) + "." + memberExpression.Member.Name; 
      } 
      if (memberExpression == null) 
      { 
       throw new ArgumentException("Unknown Expression type:"+expression.GetType().Name); 
      } 
      if (memberExpression.Member.MemberType == MemberTypes.Field) 
      { 
       var f = Expression.Lambda(memberExpression).Compile(); 
       object value = f.DynamicInvoke(); 
       return value.ToString(); 
      } 
      return memberExpression.Member.Name; 
     } 
     private string PropertyName(BinaryExpression binaryExpression) 
     { 
      if (typeof(IEnumerable).IsAssignableFrom(binaryExpression.Left.Type)) 
      { 
       return PropertyName(binaryExpression.Left) + "[" + PropertyName(binaryExpression.Right) + "]"; 
      } 
      return PropertyName(binaryExpression.Left) + "." + PropertyName(binaryExpression.Right); 
     } 

    } 

    public class Source 
    { 
     public int Easy { get; set; } 
     public Level2 Not { get; set; } 
    } 

    public class Level2 
    { 
     public Level3 So { get; set; } 
    } 
    public class Level3 
    { 
     public int Easy { get; set; } 
    } 

    public class Difficult 
    { 
     public int[] ImLost { get;set; } 
    } 
}