2017-10-21 65 views
1

我在一些代碼創建此表達式:表達`噸=>(t.SomeProperty作爲對象)`是指一種方法,而不是一個屬性

t => (t.SomeProperty As Object) 

和現在正在嘗試獲取屬性-name(SomeProperty)通過這個小片段(從網上找來的很長一段時間的自我):

public static PropertyInfo GetPropertyInfo<TSource, TProperty> 
     (TSource source, Expression<Func<TSource, TProperty>> propertyLambda) { 
     var type = typeof(TSource); 

     var member = propertyLambda.Body as MemberExpression; 
     if (member == null) 
      throw new ArgumentException($"Expression '{propertyLambda}' refers to a method, not a property."); 

     var propInfo = member.Member as PropertyInfo; 
     if (propInfo == null) 
      throw new ArgumentException($"Expression '{propertyLambda}' refers to a field, not a property."); 

     if (type != propInfo.ReflectedType && !type.IsSubclassOf(propInfo.ReflectedType)) 
      throw new ArgumentException($"Expresion '{propertyLambda}' refers to a property that is not from type {type}."); 

     return propInfo; 
    } 

但你也知道,propertyLambda.Body as MemberExpression始終爲空,導致此:t => (t.Some1 As Object)不是財產指。在這種情況下,有沒有辦法獲得物業名稱?

回答

4

C#as操作轉化爲Expression.TypeAs,和C#轉換操作符轉換要麼Expression.ConvertExpression.ConvertChecked。如您所見,它們都是UnaryExpression類型,因此您可以使用Operand屬性提取操作數表達式。你可以在一個循環中做到這一點,以支持多個強制轉換。

付諸行動,更換

var member = propertyLambda.Body as MemberExpression; 

var operand = propertyLambda.Body; 
while (operand.NodeType == ExpressionType.TypeAs || operand.NodeType == ExpressionType.Convert || operand.NodeType == ExpressionType.ConvertChecked) 
    operand = ((UnaryExpression)operand).Operand; 
var member = operand as MemberExpression; 
0

我會推薦這:

PropertyInfo info = t.GetType().GetProperty("SomeProperty", 
    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
// Use these binding flags to get a member of any visibility. 

它返回給定名稱的屬性PropertyInfo

如果您不想明確處理名稱,請使用nameof(t.SomeProperty)

您可能還會發現方法.GetProperties有用於獲取特定類型的所有屬性。

1

在你的情況,你需要看看演員的一元表達式的操作數。

((propertyLamdba.Body as UnaryExpression).Operand as MemberExpression).Member 

爲了使它在編程上更安全,您應該檢查您的propertyLamba。 喜歡的東西:

if (propertyLamdba.Body.NodeType == ExpressionType.TypeAs) 
    member = ((propertyLamdba.Body as UnaryExpression).Operand as MemberExpression).Member 
相關問題