Как реализовать шаблон стратегии с использованием 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
    }
}
Другие вопросы по тегам