动态MemberExpression [英] Dynamic MemberExpression
本文介绍了动态MemberExpression的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想要创建一个只有字段名称的MemberExpression;例如:
I am wanting to create a MemberExpression knowing only the field name; eg:
public static Expression<Func<TModel, T>> GenerateMemberExpression<TModel, T>(string fieldName)
{
PropertyInfo fieldPropertyInfo;
fieldPropertyInfo = typeof(TModel).GetProperty(fieldName);
var entityParam = Expression.Parameter(typeof(TModel), "e"); // {e}
var columnExpr = Expression.MakeMemberAccess(entityParam, fieldPropertyInfo); // {e.fieldName}
var lambda = Expression.Lambda(columnExpr, entityParam) as Expression<Func<TModel, T>>; // {e => e.column}
return lambda;
}
上面的问题是字段类型必须是强类型的。传递对象作为字段类型不起作用。有没有办法产生这个?即使是动态LINQ也不会起作用。
The problem with the above is that the field type must be strongly typed. Passing "object" in as the field type doesn't work. Is there any way to generate this? Even Dynamic LINQ doesn't appear to work.
推荐答案
您的代码有一些问题:
- 您的方法的参数称为
fieldName
,但您正在获取属性<使用它。 - 您正在使用非通用的
Expression.Lambda
方法来生成表达式,可以选择如果传递给该方法的type-argumentT
与属性类型不同,则不适当的委托类型。在这种情况下,从表达式到方法的返回类型的转换将失败并计算为
null
。解决方案:使用通用Lambda
方法与适当的类型参数。 - 如果您解决第二个问题,当可以从property-type到
T $的安全参考转换时,事情会很顺利c $ c>,但是如果需要更复杂的转换,例如拳击/提升。解决方案:使用
Expression.Convert
方法。
- The parameter to your method is called
fieldName
, but you are getting a property out with it. - You are using the non-generic
Expression.Lambda
method to generate the expression, which may choose an inappropriate delegate-type if the type-argumentT
passed to the method is not the same as the property-type. In this case, theas
cast from the expression to the method's return-type will fail and evaluate tonull
. Solution: Use the genericLambda
method with the appropriate type-arguments. No casting required. - If you solve the second issue, things will work fine when a safe reference-conversion is available from the property-type to
T
, but not when more complicated conversions such as boxing / lifting are required. Solution: Use theExpression.Convert
method where necessary.
以下是解决这些问题的示例的更新:
Here's an update to your sample that addresses these issues:
public static Expression<Func<TModel, T>> GenerateMemberExpression<TModel, T>
(string propertyName)
{
var propertyInfo = typeof(TModel).GetProperty(propertyName);
var entityParam = Expression.Parameter(typeof(TModel), "e");
Expression columnExpr = Expression.Property(entityParam, propertyInfo);
if (propertyInfo.PropertyType != typeof(T))
columnExpr = Expression.Convert(columnExpr, typeof(T));
return Expression.Lambda<Func<TModel, T>>(columnExpr, entityParam);
}
这将使所有以下呼叫成功:
This will make all of the following calls succeed:
GenerateMemberExpression<FileInfo, string>("Name");
GenerateMemberExpression<string, int>("Length");
// Reference conversion
GenerateMemberExpression<FileInfo, object>("Name");
//Boxing conversion
GenerateMemberExpression<string, object>("Length");
//Lifted conversion
GenerateMemberExpression<string, int?>("Length");
这篇关于动态MemberExpression的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文