我正在尝试从MemberExpression
的实例中检索属性的值。
这是我到目前为止所做的:
protected override void VisitMember(Context context, MemberExpression node)
{
var propertyInfo = node.Member as PropertyInfo;
if(propertyInfo != null)
{
var v = propertyInfo.GetValue(node.Member , null);
val = Convert.ToString(v);
}
context.State.Append(val);
}
根据我采用的方法,有两个问题:我不知道预期的类型(字符串,整数等等),和/或我无法从{{1}访问实例}。
我正在向T-SQL转换器写一个小的lambda表达式。例如,MemberExpression
会转换为(u)=> u.FirstName == u.LastName;
。我几乎让它工作了!
更新
我尝试了以下代码:
FirstName = 'chuck'
它不起作用。我收到以下错误:
...
var propertyInfo = node.Member as PropertyInfo;
if(propertyInfo != null)
{
var o = propertyInfo.GetValue(node.Expression, null);
}
...
更新2
这就是我想要实现的目标:
System.Reflection.TargetException : Object does not match target type.
但我在编译时不知道 public static Func<T, object> GetValueGetter<T>(this PropertyInfo propertyInfo)
{
if (typeof(T) != propertyInfo.DeclaringType)
{
throw new ArgumentException();
}
var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
var property = Expression.Property(instance, propertyInfo);
var convert = Expression.TypeAs(property, typeof(object));
return (Func<T, object>)Expression.Lambda(convert, instance).Compile();
}
。
答案 0 :(得分:4)
我不知道预期的类型(字符串,整数等等),
我无法从MemberExpression
访问该实例
使用MemberExpression.Expression
- 显然这是另一个表达式,因为你可能有:
foo.GetBar(20).ToString().Length
在这种情况下,Length
属性为MemberExpression
,但Expression
属性会为MethodCallExpression
提供ToString
。
答案 1 :(得分:0)
我无法从MemberExpression访问该实例。
在您的示例u => u.FirstName == "chuck"
中,没有可以获取FirstName
属性的实例。
我认为你实际上想要属性的名称 - 这是node.Member.Name
(在你的例子中是“FirstName”)。请注意,这适用于所有MemberInfo
,而不仅仅是PropertyInfo
,因此字段也可以正常工作。 (你可能还想测试,因为事件也是成员表达式,但在这里没有意义。)
我不知道预期的类型(字符串,整数等等),
预期类型为PropertyInfo.PropertyType
或FieldInfo.FieldType
。