我正在處理項目以通用方式篩選列表。我在運行時檢索到IEnumerable<T>
,但我不知道T
是什麼。我需要將我檢索的列表轉換爲IEnumerable<T>
而不是IEnumerable
,因爲我需要擴展方法,如ToList
和Where
。這是我的代碼。如何將`IEnumerable <Unknown T>`轉換爲`IEnumerable <Whatever>`
private IList<object> UpdateList(KeyValuePair<string, string>[] conditions)
{
// Here I want to get the list property to update
// The List is of List<Model1>, but of course I don't know that at runtime
// casting it to IEnumerable<object> would give Invalid Cast Exception
var listToModify = (IEnumerable<object>)propertyListInfoToUpdate.GetValue(model);
foreach (var condition in conditions)
{
// Filter is an extension method defined below
listToModify = listToModify.Filter(condition .Key, condition .Value);
}
// ToList can only be invoked on IEnumerable<T>
return listToModify.ToList();
}
public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, string propertyName, object value)
{
var parameter = Expression.Parameter(typeof(T), "x");
var property = Expression.Property(parameter, propertyName);
var propertyType = ((PropertyInfo)property.Member).PropertyType;
Expression constant = Expression.Constant(value);
if (((ConstantExpression)constant).Type != propertyType)
{ constant = Expression.Convert(constant, propertyType); }
var equality = Expression.Equal(property, constant);
var predicate = Expression.Lambda<Func<T, bool>>(equality, parameter);
var compiled = predicate.Compile();
// Where can only be invoked on IEnumerable<T>
return source.Where(compiled);
}
同時請注意,我不能檢索這樣
((IEnumerable)propertyListInfoToUpdate.GetValue(model)).Cast<object>()
名單,因爲它會產生在Filter
extention
ParameterExpression of type 'Model1' cannot be used for delegate parameter of type 'System.Object'
這對我來說看起來像一個非常合理的問題,而不是那種肯定應該被低估而沒有任何評論的那種。 –
爲什麼不給'UpdateList'一個泛型類型參數? 'UpdateList'。並輸入'propertyListInfoToUpdate.GetValue(model)'作爲參數(無論如何,這是更好的方法,因爲現在你的方法依賴於外部狀態)。 –
@GertArnold同樣的問題仍然存在,因爲外部調用者仍然不知道什麼是「T」。我所知道的只是我需要檢索的財產,沒有更多。 – Ayman