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);
我构建了一个框架,允许在 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);