Использование dynamic
здесь мало что дает: вам лучше использовать дженерики, если вы можете:
IEnumerable<T> FilterUsers<T>(IEnumerable<T> users, string selectedField, string selectedValue)
{
var userParameter = Expression.Parameter(typeof(T));
var userSelectedField = Expression.Property(userParameter, selectedField);
// etc...
}
Если вам нужно использовать dynamic
, тогда вам нужно получить тип времени выполнения каждого пользователя, используя .GetType()
. Однако имейте в виду, что ничто не мешает кому-то передать IEnumerable
, содержащий множество различных типов объектов, и им не обязательно иметь свойство с именем selectedField
!
Или они могут передают множество различных типов объектов, каждый из которых имеет свойство selectedField
, но они имеют разные свойства (например, class A { public string Foo { get; set; } }
и class B { public string Foo { get; set; } }
- эти два свойства Foo
различны).
Таким образом, вам придется вызывать .GetType()
для каждого из них, что означает, что вы не сможете получить преимущества в производительности от использования скомпилированных выражений.
Если вы можете гарантировать, что все элементы Если вы используете тот же тип, вы можете сделать что-то вроде:
private static IEnumerable<dynamic> FilterCollection(IEnumerable<dynamic> collection, string property, string value)
{
if (!collection.Any()) return collection;
var collectionItemType = collection.First().GetType();
var userParameter = Expression.Parameter(typeof(object));
var convertedUser = Expression.Convert(userParameter, collectionItemType);
var userSelectedField = Expression.Property(convertedUser, selectedField);
...
}
Остерегайтесь, однако, вы перечисляете users
дважды, что, вероятно, плохо. Вы могли бы лучше получить IEnumerator
самостоятельно и работать с ним явно.