2017-10-21 31 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 
相关问题