表达式树的转换问题
作者:互联网
我有上一个SO问题的表达式树函数.它基本上允许将数据行转换为特定的类.
除非您要处理的数据类型可以更大或更小(例如Int32 / Int64),否则这段代码可以正常工作.
当从Int64到Int32的值适合Int32时,代码将引发无效的强制转换异常(例如3000中的数字).
我是不是该?
>尝试在代码中解决此问题? (如果是,是否有任何指针?)
>保持原样.
private Func<SqlDataReader, T> getExpressionDelegate<T>()
{
// hang on to row[string] property
var indexerProperty = typeof(SqlDataReader).GetProperty("Item", new[] { typeof(string) });
// list of statements in our dynamic method
var statements = new List<Expression>();
// store instance for setting of properties
ParameterExpression instanceParameter = Expression.Variable(typeof(T));
ParameterExpression sqlDataReaderParameter = Expression.Parameter(typeof(SqlDataReader));
// create and assign new T to variable: var instance = new T();
BinaryExpression createInstance = Expression.Assign(instanceParameter, Expression.New(typeof(T)));
statements.Add(createInstance);
foreach (var property in typeof(T).GetProperties())
{
// instance.MyProperty
MemberExpression getProperty = Expression.Property(instanceParameter, property);
// row[property] -- NOTE: this assumes column names are the same as PropertyInfo names on T
IndexExpression readValue = Expression.MakeIndex(sqlDataReaderParameter, indexerProperty, new[] { Expression.Constant(property.Name) });
// instance.MyProperty = row[property]
BinaryExpression assignProperty = Expression.Assign(getProperty, Expression.Convert(readValue, property.PropertyType));
statements.Add(assignProperty);
}
var returnStatement = instanceParameter;
statements.Add(returnStatement);
var body = Expression.Block(instanceParameter.Type, new[] { instanceParameter }, statements.ToArray());
var lambda = Expression.Lambda<Func<SqlDataReader, T>>(body, sqlDataReaderParameter);
// cache me!
return lambda.Compile();
}
更新:
我现在已经放弃,认为这不值得.从下面的评论中,我得出的结论是:
if (readValue.Type != property.PropertyType)
{
BinaryExpression assignProperty = Expression.Assign(getProperty, Expression.Convert(Expression.Call(property.PropertyType, "Parse", null, new Expression[] { Expression.ConvertChecked(readValue, typeof(string)) }), property.PropertyType));
statements.Add(assignProperty);
}
else
{
// instance.MyProperty = row[property]
BinaryExpression assignProperty = Expression.Assign(getProperty, Expression.Convert(readValue, property.PropertyType));
statements.Add(assignProperty);
}
我不认为我离得太远,如果您发现问题,可以随时完成并发布答案:)
解决方法:
您可以在分配值之前使用Expression.ConvertChecked
而不是Expression.Convert尝试通过“转换已检查”来修复它.
现在无法尝试,但这应该可以解决您描述的情况…
编辑-根据评论,这可能是拳击问题:
在这种情况下,您可以尝试使用Expression.TypeAs
或Expression.Unbox
进行转换,或使用Expression.Call
调用进行转换的方法…有关调用的示例,请参见http://msdn.microsoft.com/en-us/library/bb349020.aspx
标签:c,expression-trees 来源: https://codeday.me/bug/20191102/1989912.html