2017-02-03 1 views
3

私は、どの列がマスターソート列であるかに応じて、テーブル内のレポートデータのカスケードソートを可能にするフレームワークを構築しました。特定の重要なケースを除いて、大部分は機能します:フィールドのプロパティが値型の場合。私は、次のエラーメッセージが表示されます。ValueTypeの動的表現生成の問題

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>>()を処理するときに例外がスローされます。ランタイムまで型がわからないときに、プロパティボックスに必要なもの、または正しい値を返すか?あなたがオブジェクト型にあなたの財産Expressionを変換する必要があり

答えて

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

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

それを 'Expression.Lambda <>()'呼び出しで使用しますか? – JNYRanger

+0

@JNYRangerはい、私はすべてのパラメータでそれをやっていますが、おそらく参照型の変換は必要ではありません –

+0

参照型には必要ありませんが、後ですべての型で機能するように最適化します。 – JNYRanger