As an alternative solution, you can use the following approach, which allows you to specify either a filter field or a filter function:
var adresses = new List<Address>{ new Address() { City = "ABC", Country = "USA" }, new Address() { City = "BC", Country = "USA" }, new Address() { City = "C", Country = "UK" } }; var filterValues = new List<string> { "B", "UK", "U" }; // var FilterContains = filterValues.@Specify ((values, value) => values.Contains(value)); var FilterStartsWith = filterValues.@Specify ((values, value) => values.Any(v => value.StartsWith(v))); // var AdressesByCity = adresses.@Specify (a => a.City); var adressesByCitiesContains = AdressesByCity(filterValues, FilterContains); // B->{ABC;USA},{BC;USA} var adressesByCitiesStartsWith = AdressesByCity(filterValues, FilterStartsWith);// B->{BC;USA} // var AdressesByCountry = adresses.@Specify (a => a.Country); var adressesByCountriesContains = AdressesByCountry(filterValues, FilterContains);//U,UK-> {C;UK} var adressesByCountriesStartsWith = AdressesByCountry(filterValues, FilterStartsWith); //U,UK->{ABC;USA},{BC;USA}{C;UK}
Here the @Specify extension @Specify implemented as follows:
public static class @SpecifyExtension { public static Func<IEnumerable<V>, Func<IEnumerable<V>, V, bool>, IEnumerable<U>> @Specify<U, V>(this IEnumerable<U> source, Func<U, V> selector) { return (values, predicate) => source.Where(x => predicate(values, selector(x))); } public static Func<IEnumerable<TValue>, TValue, bool> @Specify<TValue>(this IEnumerable<TValue> source, Func<IEnumerable<TValue>, TValue, bool> func) { return func;