3

遇到与使用抽象类相结合的存储库模式的问题。

我有一个存储库,它实现了一个返回抽象类型的 ICollection 的方法。

这是我的抽象类:

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>一个抽象类型
  • 我希望我的服务(每种具体类型都有一个)基于该单一存储库方法返回具体类型列表

这只是 LINQ 语法的一个例子吗?还是我的设计模式完全错误?

4

2 回答 2

7
repository.GetAllLocations().OfType<Country>().ToList();

你甚至不需要LocationType枚举

于 2010-07-30T03:47:24.110 回答
2

您的问题的解决方案非常简单,您需要在 LINQ 表达式中创建一个新的 Country :

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

我认为您将通用ToList<T>方法误认为能够创建新类型的列表,其中T总是从源集合中推断出来。通常,每当您想将一种类型的集合转换为另一种类型的项目集合时,您都会使用Select.

于 2010-07-30T03:39:16.030 回答