Роб указал, как вы можете это сделать (хотя более классический подход LINQ может занять Expression<Func<Item,bool>>
и, возможно, вернуть IQueryable<IFamily>
).
Хорошей новостью является то, что если вы хотите использовать предикат с LINQ-to-Objects (для вашего xml-сценария), вы можете просто использовать:
Predicate<Item> func = predicate.Compile();
или (для другой подписи):
Func<Item,bool> func = predicate.Compile();
и у вас есть делегат (func
) для тестирования ваших объектов.
Проблема, однако, в том, что это кошмар для модульного теста - вы можете только интеграция проверить его.
Проблема в том, что вы не можете надежно высмеивать (с помощью LINQ-to-Objects) что-либо, связанное со сложными хранилищами данных; например, следующее будет хорошо работать в ваших модульных тестах, но не будет работать «по-настоящему» с базой данных:
var foo = GetItems(x => SomeMagicFunction(x.Name));
static bool SomeMagicFunction(string name) { return name.Length > 3; } // why not
Проблема в том, что только некоторые операции могут быть переведены в TSQL. Вы получаете ту же проблему с IQueryable<T>
- например, EF и LINQ-to-SQL поддерживают разные операции над запросом; даже First()
ведет себя по-разному (EF требует, чтобы вы сначала явно указали его, а LINQ-to-SQL - нет).
Итак, в итоге:
- может работать
- но подумайте, хотите ли вы это сделать; более классический интерфейс хранилища / службы черного ящика может быть более тестируемым