2017-02-03 78 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); 
     } 
    } 

異常處理Expression.Lambda<Func<T, object>>()時當T中選擇的屬性是一個值類型的異常。什麼是需要屬性框或返回正確的值時,類型不知道直到運行時?

回答

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

你有你的財產Expression轉換爲對象的類型:

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

然後在'Expression.Lambda <>()'調用中使用它? – JNYRanger

+0

@JNYRanger是的,我會爲每個參數做,但也許轉換爲ref類型不是必要的 –

+0

是的它沒有必要爲引用類型,但我會稍後優化它,一旦事情適用於所有類型。 – JNYRanger