werfe Ich arbeite an einem Projekt, um eine Liste in einer allgemeinen Weise zu filtern. Ich erhalte eine IEnumerable<T>
zur Laufzeit, aber ich weiß nicht, was T
ist. Ich muss die Liste, die ich abrufe, in IEnumerable<T>
und nicht in IEnumerable
umwandeln, da ich Erweiterungsmethoden wie ToList
und Where
benötige. Hier ist mein Code.Wie man ein `IEnumerable <Unknown T>` auf `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);
}
Bitte beachten Sie auch, dass ich die Liste wie dies
((IEnumerable)propertyListInfoToUpdate.GetValue(model)).Cast<object>()
abrufen kann, da es
ParameterExpression of type 'Model1' cannot be used for delegate parameter of type 'System.Object'
Das sieht wie eine sehr vernünftige Frage für mich aus, nicht die Art, die sicherlich ohne Kommentar heruntergestimmt werden sollte. –
Warum geben Sie 'UpdateList' keinen generischen Typparameter? 'UpdateList'. Und geben Sie 'propertyListInfoToUpdate.GetValue (model)' als Parameter ein (was sowieso besser ist, da Ihre Methode jetzt vom externen Status abhängig ist). –
@GertArnold Das gleiche Problem wird immer noch da sein, weil der externe Anrufer immer noch nicht weiß, was 'T' ist. Alles, was ich weiß, ist die Eigenschaft, die ich abrufen muss, nichts mehr. – Ayman