我正在处理项目以通用方式筛选列表。我在运行时检索到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