Проблема с шаблоном репозитория и абстрактными классами - PullRequest
3 голосов
/ 30 июля 2010

Возникла проблема с шаблоном репозитория в сочетании с использованием абстрактных классов.

У меня есть репозиторий, который реализует единственный метод, возвращающий ICollection абстрактного типа.

Вот мой abstract class:

public abstract class Location
{
   public abstract string Name { get; set; }
   public abstract LocationType Type { get; }
}

Вот конкретная реализация этого абстрактного класса:

public class Country : Location
{
   public override string Name { get; set; }
   public override LocationType Type { get { return LocationType.Country; } }
}

Вот мой репозиторий :

public class LocationsRepository : Locations.Repository.ILocationsRepository
{
   public ICollection<Location> GetAllLocations()
   {
      Country america = new Country { Name = "United States" };
      Country australia = new Country { Name = "Australia" };
      State california = new State { Name = "California", Country = america };

      return new List<Location>() { america, australia, california };
    }
}

Пока все хорошо.

Теперь служба :

public class CountryService : ICountryService
{
   private ILocationsRepository repository;

   public CountryService()
   {
      // in reality this is done by DI, but made 'greedy' for simplicity.
      this.repository = new LocationsRepository();
   }

   public List<Country> GetAllCountries()
   {
      // errors thrown by compiler
      return repository.GetAllLocations()
                       .Where(l => l.Type == LocationType.Country)
                       .ToList<Country>();
   }
}

Проблема есть.Я пытаюсь вернуть список конкретных типов (Country) из репозитория, который возвращает ICollection<T> абстрактного типа.

Получить 2 ошибки времени компиляции:

'System.Collections.Generic.IEnumerable' не содержит определения для 'ToList' и лучшая перегрузка метода расширения 'System.Linq.ParallelEnumerable.ToList (System.Linq.ParallelQuery)' имеет некоторые недопустимые аргументы

и

Аргумент экземпляра: невозможно преобразовать из 'System.Collections.Generic.IEnumerable' в 'System.Linq.ParallelQuery'

Итак, какМогу ли я реализовать этот шаблон?

Я могу в некотором роде понять проблему (вы не можете создать экземпляр абстрактного типа), поэтому Enumerator (.ToList) пытается создать его, отсюда и ошибка?

В случае, если вы не понимаете, что я пытаюсь сделать:

  • Я хочу, чтобы мой репозиторий возвращал ICollection<T> абстрактного типа
  • Мне нужны мои услуги (у меня будет один для каждого конкретного типа), чтобы вернуть List конкретных типов, основанных на этом единственном методе репозитория

Это всего лишь случай синтаксиса LINQ?Или мой шаблон дизайна совершенно неверен?

Ответы [ 2 ]

7 голосов
/ 30 июля 2010
repository.GetAllLocations().OfType<Country>().ToList();

А вам даже не нужно перечисление LocationType

2 голосов
/ 30 июля 2010

Решение вашей проблемы довольно простое, вам нужно создать новую страну в выражении LINQ:

return repository.GetAllLocations()
    .Where(l => l.Type == LocationType.Country)
    .Select(l => l as Country).ToList();

Я думаю, что вы ошиблись в использовании общего метода ToList<T> для возможностисписок нового типа, где T всегда выводится из исходной коллекции.Обычно, когда вы хотите преобразовать коллекцию одного типа в коллекцию элементов другого типа, вы используете Select.

...