鑑於我有一個IEnumerable<T>
,其中T
是任何對象,我怎麼能從它中選擇一個特定的屬性,因爲我知道在運行時的一個屬性名稱的名稱作爲一個字符串?如何在運行時在IEnumerable <T>上創建動態選擇?
例如:
var externalIEnumerable = DataPassedFromConsumingCode(); // `IEnumerable<T>`
string knownPropertyName = "Foo";
var fooSelect = externalIEnumerable.Select(...);
從本質上說,我明明只是做externalIEnumerable.Select(x=> x.Foo);
,但我需要執行此Select
在運行時,當我沒有當它最初創建了控制。
-
答:基於AlanT的答案,這是我實際做:
public Expression<Func<TItem, object>> SelectExpression<TItem>(string fieldName)
{
var param = Expression.Parameter(typeof(TItem), "item");
var field = Expression.Property(param, fieldName);
return Expression.Lambda<Func<TItem, object>>(field,
new ParameterExpression[] { param });
}
我一直是作爲一種表達,因爲調用Compile
造成的IQueryable被枚舉,其意味着數據庫被不必要地擊中。因此,要使用它,我只是做到以下幾點:
string primaryKey = _map.GetPrimaryKeys(typeof(TOriginator)).Single();
var primaryKeyExpression = SelectExpression<TOriginator>(primaryKey);
var primaryKeyResults = query.Select(primaryKeyExpression).ToList();
你可以在IEnumerable中約束T嗎? – Jason
這不是一個特定於linq的問題,對吧?你問的是如何通過名稱而不是靜態地在代碼中動態訪問屬性? –
爲了澄清,你的T可以是任何東西,你的財產可以是任何東西,你只需要將屬性名稱作爲一個字符串? –