遇到存储库模式的问题并结合使用抽象类。
我有一个存储库,它实现了一个返回抽象类型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语法的一个例子吗?或者我的设计模式完全错了?
答案 0 :(得分:7)
repository.GetAllLocations().OfType<Country>().ToList();
你甚至不需要LocationType
enum
答案 1 :(得分:2)
您的问题的解决方案非常简单,您需要在LINQ表达式中创建一个新的国家/地区:
return repository.GetAllLocations()
.Where(l => l.Type == LocationType.Country)
.Select(l => l as Country).ToList();
我认为您错误地将通用ToList<T>
方法设置为能够创建新类型的列表,而始终从源集合中推断出T
。通常,只要您想将一种类型的集合转换为另一种类型的项集合,就可以使用Select
。