2

私は次のコードを持っていると言います:

public class Pond
{
  public List<Frog> Frogs { get; set; }
  public List<MudSkipper> MudSkippers { get; set; }
  public List<Eel> Eels { get; set; }
}

public class Frog: IAquaticLife
{

}



public class MudSkipper: IAquaticLife
{

}



public class Eel: IAquaticLife
{

}

ここで、特定の池に対してこれらのタイプのリストを返すジェネリックメソッドを作成します。

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
   return Uow.GetByID<Pond>(pondId).Eels;
}

さて、私が持っているものは、その池のすべてのウナギを返します。私がやりたかったのは、すべてのTを返すことでした。

だから私が電話GetByPond<MudSkipper>(1)した場合、それはすべてのマッドスキッパーを返すでしょう。

誰もがこれを行う方法を知っていますか?

4

3 に答える 3

5

のようなものはどうですか

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
   return from t in Uow.GetByID<Pond>(pondId).AquaticLife() 
          where (typeof(t) == typeof(T)) select t;
}

または単に(@DStanleyが答えを変更する前に指摘したアプローチを使用して)

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
   return Uow.GetByID<Pond>(pondId).AquaticLife().OfType<T>();
}

そのためには、 IAquaticLifeを実装する特定の池にいるすべてのタイプのクリーチャーを返すためにUow.GetByID(int id)が必要です。ただし、別の方法は、 IAquaticLifeのさまざまな実装者の知識をジェネリックメソッドにハードコーディングすることです。それは良い考えではありません。

アップデート

現在、Pondには、 EelsMudskippersなどの個別のコレクションがあります。Pondと上記の一般的な方法の両方を変更する必要があるため、コードの進化に合わせてIAquaticLifeを実装するものを追加する場合は、脆弱になります。

水生生物の種類ごとに個別のメソッドを使用する代わりに、IAquaticLifeを実装する池のすべてを返す単一のメソッドを使用することをお勧めします

public class Pond
{
    public IEnumerable<IAquaticLife> AquaticLife() { ... }
}

この仮定で上記のコードを更新しました。

Pondインスタンスを持っていて、たとえばEelsだけがこれを実行できるようにしたい場合は、次のようにします。

var eels = pond.AquaticLife().OfType<Eels>();
于 2012-08-28T02:51:29.760 に答える
2

これを試して:

return Uow.GetByID<Pond>(pondId).OfType<T>();

編集

コレクションは個別のプロパティにあるため、switchブロックを使用してタイプに基づいて適切なプロパティを返すか、リフレクションを使用してタイプ名に基づいてプロパティを取得できます。

要件に基づいたより良い設計はList<IAquaticLife>、個別のプロパティではなく、すべての生き物を格納するプライベートを用意することですが、現時点ではそれを行うことはできないと思います。

スイッチの例は次のとおりです。

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
    switch(typeof(T))
    {
        case typeof(Eel):
            return Uow.GetByID<Pond>(pondId).Eels;
        //etc.
        default:
            throw new ApplicationException(string.Format("No property of type {0} found",typeof(T).Name));
    }
}
于 2012-08-28T02:52:46.393 に答える
-1
public Pond GetByPond(int pondId)
{
    return Uow.GetByID<Pond>(pondId);
}

カエルが必要な場合は、次のようにします。

var frogs = xxx.GetByPond(1).Frogs;

MudSkippers が必要な場合は、次のようにします。

var mudSkippers = xxx.GetByPond(1).MudSkippers;

等々。

に電話できる場合はGetByPond<Frog>(1)、電話できますGetByPond(1).Frogs

いずれにせよ がわからない場合はT、それらすべてのコレクションを作成し、タイプ別にフィルター処理する必要があります。これは、中間サブタイプがある場合にも役立ちます。

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
    var pond = Uow.GetByID<Pond>(pondId);
    var life = pond.Frogs.Union(pond.Eels).Union(pond.MudSkippers);
    return life.OfType<T>();
}

ただし、コレクションをフィルタリングするためだけにコレクションを連結しています。

于 2012-08-28T04:52:32.953 に答える