Dynamic Expression Generation Issues with ValueTypes

独自空忆成欢 提交于 2020-01-14 19:42:10

问题


I built a framework that allows for cascaded sorting of report data in a table depending on what column is the master sorted column. It works for the most part, except in one specific, but important case: when the field's property is a value type. I receive the following error message:

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

I know that this means I need to box the value of the ValueType, but I'm not completely sure how to in this particular situation. Per some research and this SO answer I believe that I need to use Expression.Convert in some way.

My code below is what generates the expressions. The generic type parameter T is the type of the "row" of data. The GetFullSortOrder() simply returns an array of strings that represent the names of the columns (properties) in the type T that will also be sorted.

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);
        }
    }

The exception is thrown when processing Expression.Lambda<Func<T, object>>() when the Property selected in T is of a ValueType. What is needed to property box or return the correct value when the types aren't known until run-time?


回答1:


You said it - you need to use Expression.Convert and pass typeof(object). If you want to simulate what the C# compiler does, you should do it only for value types:

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



回答2:


You have to convert your property Expression to an object type:

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


来源:https://stackoverflow.com/questions/42032468/dynamic-expression-generation-issues-with-valuetypes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!