ValueType 的动态表达式生成问题

Dynamic Expression Generation Issues with ValueTypes

我构建了一个框架,允许在 table 中对报告数据进行级联排序,具体取决于哪个列是主排序列。它在大多数情况下都有效,但在一个特定但重要的情况下除外:当字段的 属性 是值类型时。我收到以下错误消息:

System.ArgumentException: Expression of type 'System.Int32' cannot be used for return type 'System.Object'

我知道这意味着我需要装箱 ValueType 的值,但我不完全确定在这种特定情况下如何操作。根据一些研究和 this SO answer I believe that I need to use Expression.Convert 以某种方式。

我下面的代码是生成表达式的代码。泛型类型参数 T 是 "row" 数据的类型。 GetFullSortOrder() 只是 return 一个字符串数组,表示类型 T 中也将被排序的列(属性)的名称。

public IEnumerable<Expression<Func<T, object>>> GetExpressions<T>(string sortedColumn) where T : IReportRecord
    {
        var columns = GetFullSortOrder(sortedColumn)
        var typeParameter = Expression.Parameter(typeof(T));
        foreach (var c in columns)
        {
            var propParameter = Expression.Property(typeParameter, c);
            yield return Expression.Lambda<Func<T, object>>(propParameter, typeParameter);
        }
    }

当T中选择的属性为ValueType时,处理Expression.Lambda<Func<T, object>>()时抛出异常。当类型直到 运行 时间才知道时,属性 框或 return 正确值需要什么?

您必须将 属性 Expression 转换为对象类型:

var propParameterObj = Expression.Convert(propParameter, typeof(object));

你说了 - 你需要使用 Expression.Convert 并通过 typeof(object)。如果你想模拟 C# 编译器做什么,你应该只对值类型做:

Expression result = propParameter;
if (typeof(T).IsValueType)
    result = Expression.Convert(result, typeof(object));
yield return Expression.Lambda<Func<T, object>>(result, typeParameter);