2015-08-21 27 views
2

我想創建如下形式的表達:表達「System.Object的」

e => e.CreationDate; 

CreationDatelong型的,但是我想該表達式改爲返回object

我想使用object作爲返回類型,因爲表達式是基於查詢參數在運行時動態構建的。查詢參數指定屬性的表達來訪問,如:

> entities?order=creationDate 
> entities?order=score 

正如你所看到的,我可以通過不同類型不同的屬性順序,因此返回類型object,讓我來構建表達儘可能通用。

的問題是,當我嘗試創建表達式:

ParameterExpression entityParameter = Expression.Parameter(typeof(Entity), "e"); 
Expression propertyAccess = Expression.Property(entityParameter, property); 
Expression<Func<Entity, object>> result = Expression.Lambda<Func<Entity, object>>(propertyAccess, entityParameter); 

我得到以下異常:

類型「System.Int64」的表達,不能用於返回類型 'System.Object'

很奇怪,因爲據我所知,所有類型從object延伸(它看到ms多態性尚未被表達式樹支持)。

不過,我在網上搜索,並與此類似的問題絆倒:

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

Jon Skeet的回答,我修改了我的最後一行:

Expression<Func<Entity, object>> result = Expression.Lambda<Func<Entity, object>>(Expression.Convert(propertyAccess, typeof(object)), entityParameter); 

這工作正常,但它不會生成我想要的表達式。相反,它生成這樣的:

e => Convert(e.CreationDate) 

如果表達式體不是MemberExpression(即,部件訪問操作)我不能使用此解決方案,因爲在後面的程序中的拋出異常

我一直在網上搜索一個令人滿意的答案,但找不到任何。

如何才能達到e => e.CreationDate返回類型爲object

+0

你需要構造一個'Expression >?你可以創建一個非泛型的'LambdaExpression'並且構造一個'Func '。 – Lee

+0

@Lee我想要使用相同的幫助器方法來構建任何'MemberExpression',這意味着有時我會返回一個'long',有時還會返回一個'string'。如果我不這樣做泛型,那麼我將不得不爲每個返回類型或實現複製相同的方法邏輯 –

+0

您可以使它成爲'Expression >',就像'OrderBy' in linq' IQueryable' –

回答

0

取決於你如何使用result你可以動態地委託類型Func<Entity, long>創建它,然後鍵入它作爲一個LambdaExpression

ParameterExpression entityParameter = Expression.Parameter(typeof(Entity), "e"); 
Expression propertyAccess = Expression.Property(entityParameter, property); 
var funcType = typeof(Func<,>).MakeGenericType(typeof(Entity), property.PropertyType); 
LambdaExpression result = Expression.Lambda(funcType, propertyAccess, entityParameter); 
1

簡短的回答:不,這是不可能的。值類型需要被裝箱以被視爲對象。編譯器通常會爲你做,但如果你自己構建代碼(例如表達式樹),你需要將它指定爲顯式轉換,就像你在查找到的答案中看到的那樣。如果您不能將其作爲非泛型LambdaExpression,那麼我會在您期望使用MemberExpression的情況下處理轉換大小寫,或者使用PropertyInfo,並且只在最後時刻通過Expression構造該命令。

相關問題