私は一般的な方法でリストをフィルタリングするプロジェクトに取り組んでいます。実行時にIEnumerable<T>
を取得していますが、T
が何であるかわかりません。 ToList
とWhere
のような拡張メソッドが必要なので、私が検索しているリストをIEnumerable<T>
にキャストし、IEnumerable
をキャストする必要はありません。ここに私のコードです。`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);
}
また、それは一般的なインタフェースするFilter
拡張子
ParameterExpression of type 'Model1' cannot be used for delegate parameter of type 'System.Object'
これは私にとって非常に妥当な質問のようです。 –
'UpdateList'にジェネリック型のパラメータを与えないのはなぜですか? 'UpdateList'です。また、 'propertyListInfoToUpdate.GetValue(model)'をパラメータとして入力します(これは、メソッドが外部状態に依存するためです)。 –
@GertArnold外部の呼び出し元はまだ 'T'が何であるかわからないので、同じ問題が残っています。私が知っているのは、私が検索する必要があるものです。 – Ayman