我在一些代码中创建了这个表达式:
t => (t.SomeProperty As Object)
现在我试图通过这个小片段获取属性名称(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)
不是属性引用。在这种情况下,有没有办法获得属性名称?
答案 0 :(得分:4)
C#as
运算符转换为Expression.TypeAs
,C#转换运算符转换为Expression.Convert
或Expression.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;
答案 1 :(得分:1)
在您的情况下,您需要查看作为强制转换的一元表达式的操作数。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<input type="text" title="Your name" id="name">
<button type="button" id="submit">Submit</button>
为了使程序更安全,您应该检查您的propertyLamba。 类似的东西:
((propertyLamdba.Body as UnaryExpression).Operand as MemberExpression).Member
答案 2 :(得分: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
对于获取特定类型的所有属性非常有用。