Как реализовать шаблон стратегии с использованием Generics в C#
У меня есть строка
string partialCityName
и общий список.
var city = List<City>
Я хочу сделать две вещи:
1. Фильтруйте список по имени, и я делаю это так:
var availableCities = cityList.Where(f => f.CityName.StartsWith(partialCityName));
2. Получите список символов, основанный на указанном выше var "availableCities", и я делаю это следующим образом.
var nextAvailableCharacters = avalibleCities .
Where(s => s.CityName.Length > partialCityName.Length).
Select(s => s.CityName.Substring(partialCityName.Length)[0]).ToList();
В настоящее время это происходит одним способом и работает. Однако я пытаюсь понять шаблоны проектирования и пытаюсь реализовать шаблон "Стратегия".
Итак, первый вопрос: правильный ли это шаблон? Если так, как?
Это то, что я получил до сих пор.
public interface IFilterStrategy
{
List<T> Filter<T>(List<T> filterThisData, string filter);
}
Затем:
public class FilterCityStrategy : IFilterStrategy
{
public List<City> Filter<City>(List<City> filterThisData, string partialCityName)
{
//Fails to compile cityName not member of f
return filterThisData.Where(f => f.CityName.StartsWith(partialCityName));
}
}
2 ответа
Во-первых, вы объявляете ваш интерфейс следующим образом:
public interface IFilterStrategy<T>
{
List<T> Filter(List<T> filterThisData, string filter);
}
И тогда вам нужно унаследовать от конкретного экземпляра этого интерфейса:
public class FilterCityStrategy : IFilterStrategy<City>
{
public List<City> Filter(List<City> filterThisData, string partialCityName)
{
return filterThisData.Where(f => f.CityName.StartsWith(partialCityName)).ToList<City>();
}
}
Смотрите https://repl.it/repls/UnluckyEqualRaptors
Ошибка, которую вы получили, заключалась в том, что Filter
метод был объявлен как метод шаблона с параметром шаблона City
, Это означает, что City
действует как произвольный тип в этом определении функции и, следовательно, скрывает / маскирует объявление вашего City
Класс в другом месте в вашем коде:
public List<City> Filter***<City>***(List<City> filterThisData, string partialCityName)
{
//Fails to compile cityName not member of f
return filterThisData.Where(f => f.CityName.StartsWith(partialCityName));
}
Вы можете немного расширить его, чтобы приспособить более сложную фильтрацию. Например, если у вас есть фильтр страны и фильтр города, скорее всего, фильтр города также будет иметь код страны.
interface IFilter
{
}
class CountryFilter
{
string PartialCountryName { get; set;}
}
class CityFilter
{
string CountryCode { get; set;}
string PartialCityName { get; set;}
}
interface IFilterStrategy<T,U> where U:IFilter
{
List<T> Filter(List<T> source,U filter);
}
class CountryFilterStategy : IFilterStrategy<Country,CountryFilter>
{
List<Country> Filter(List<Country> source,CountryFilter filter)
{
//logic
}
}
class CityFilterStategy : IFilterStrategy<City,CityFilter>
{
List<City> Filter(List<City> source,CityFilter filter)
{
//logic
}
}