其他分享
首页 > 其他分享> > 表达式树的转换问题

表达式树的转换问题

作者:互联网

我有上一个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.TypeAsExpression.Unbox进行转换,或使用Expression.Call调用进行转换的方法…有关调用的示例,请参见http://msdn.microsoft.com/en-us/library/bb349020.aspx

标签:c,expression-trees
来源: https://codeday.me/bug/20191102/1989912.html