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」に変換できません

では、どうすればこのパターンを実装できますか?

私は問題をある程度理解できます(抽象型をインスタンス化することはできません)ので、列挙子(.ToList)はこれをインスタンス化しようとしますか?したがってエラーですか?

私が何をしようとしているのかわからない場合:

  • ICollection<T>リポジトリが抽象型のを返すようにしたい
  • 私のサービス(具体的なタイプごとに1つあります)が、その単一のリポジトリメソッドに基づいて具体的なタイプのリストを返すようにします

これはLINQ構文の場合にすぎませんか?それとも私のデザインパターンは完全に間違っていますか?

4

2 に答える 2

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

LocationTypeそして、列挙型も必要ありません

于 2010-07-30T03:47:24.110 に答える
2

問題の解決は非常に簡単です。LINQ式で新しい国を作成する必要があります。

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 に答える