【问题标题】:Dynamic Expression Generation Issues with ValueTypesValueTypes 的动态表达式生成问题
【发布时间】:2017-02-03 20:25:13
【问题描述】:

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

System.ArgumentException:“System.Int32”类型的表达式不能用于返回类型“System.Object”

我知道这意味着我需要对 ValueType 的值进行装箱,但我不完全确定在这种特殊情况下如何操作。根据一些研究和this SO answer,我相信我需要以某种方式使用Expression.Convert

下面的代码是生成表达式的内容。泛型类型参数 T 是数据“行”的类型。 GetFullSortOrder() 只返回一个字符串数组,这些字符串表示类型 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 中选择的 Property 是 ValueType 时,处理 Expression.Lambda&lt;Func&lt;T, object&gt;&gt;() 时会引发异常。当类型直到运行时才知道时,属性框或返回正确的值需要什么?

【问题讨论】:

    标签: c# linq dynamic lambda linq-expressions


    【解决方案1】:

    您说过 - 您需要使用 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);
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 然后在Expression.Lambda&lt;&gt;()调用中使用它?
      • @JNYRanger 是的,我会为每个参数都这样做,但也许不需要转换为 ref 类型
      • 是的,对于引用类型来说,def 不是必需的,但是一旦所有类型都适用,我稍后会对其进行优化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多