ValueTypes

时间:2017-02-03 20:25:13

标签: c# linq dynamic lambda linq-expressions

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

  

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中选择的属性是ValueType时处理Expression.Lambda<Func<T, object>>()时抛出异常。如果在运行时之前不知道类型,属性框需要什么或返回正确的值?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

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