我构建了一个框架,允许对表中的报表数据进行级联排序,具体取决于哪个列是主排序列。它在很大程度上起作用,除了一个特定但重要的情况:当字段的属性是值类型时。我收到以下错误消息:
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>>()
时抛出异常。如果在运行时之前不知道类型,属性框需要什么或返回正确的值?
答案 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));