1

とから派生したタイプの異種シーケンスがあるAnimalとしFoodます。

これは、派生型のインスタンスで変換される必要があります:FedNotFedおよびBadFed

var seq1 = new[] { new Fish(), new FishFood(), new Horse(), new DogFood(), new Dog() };

に変換する必要があります

var seq2 = new [] {  new FishFed(), new HorseBadFed(), new DogNotFed() };

ロジックは次のとおりです。

  • Animal次の要素に適切な食べ物がある場合、インスタンスXXXFedが作成されます。

  • 次の要素に食べ物がある場合。しかし、そのためには良くありませんAnimal-> XXXBadFed;

  • そうでなければ、次の要素の食べ物でない場合-> XXXNotFed

次の項目を条件としてシーケンスを処理することは、反復では簡単ではありません。

IEnumerable<T>Linqまたは拡張メソッドを使用して、状態を含むシーケンス処理を抽象化するにはどうすればよいですか?

Aggregate同様のことを行うためにアキュムレータ関数を使用することを私は知っています。これは私の場合ですか?または、それを使用して新しいシーケンスを作成する方がよいでしょうか。

命令型コードなしでこのような問題を解決するためにメモ化関数を使用するのは正しいですか?

4

2 に答える 2

3

最初に Zip 関数を使用してペアを作成し、代わりにペアのコレクションを処理します。

        var seq1 = new object[] { new Fish(), new FishFood(), new Horse(), new DogFood(), new Dog() };
        var count = seq1.Length;
        var foodSeq = seq1.Skip(1).Concat(new object[]{null});
        var dinnerPairs = seq1.Zip(foodSeq, (eater, food) => Tuple.Create(eater as Animal, food as Food)).Where(t => t.Item1 != null);
        var result = dinnerPairs.Select(t => t.Item1.Feed(t.Item2));

Animal クラスの Feed メソッドは、各動物によってオーバーライドされます。たとえば、犬の場合、null の場合は DogNotFed を返し、DogFood の場合は DogFad を返し、それ以外の場合は DogBadFed を返します。厳密な命名規則がある場合は、リフレクションを使用してこれらの型を動的に作成できます。

public abstract class Animal
{
    public abstract Animal Feed(Food food);
}

編集: Feed メソッドがリフレクションを使用してロジックを解決できると思いますが、テストされていません。

public Animal Feed(Food food)
    {
        var myType = this.GetType().FullName;
        if (food == null) return GetNewObject(myType + "NotFed") as Animal;
        if( food.GetType().FullName == myType+"Food") return GetNewObject(myType+"Fed") as Animal;
        return GetNewObject(myType+"BadFed") as Animal;
    }

    public static object GetNewObject(string typeName)
    {
        try
        {
            var t = Type.GetType(typeName);
            return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
        }
        catch
        {
            return null;
        }
    }
于 2013-03-10T10:27:38.500 に答える
-1

実生活では、食べ物を食べて病気になったり満腹になったり、空腹のままになったりするのは誰の責任ですか? 動物そのものでしょう。

では、型IConsumeFoodによって実装されたインターフェースを持たないのはなぜでしょうか? AnimalそのメソッドConsumeはいくつかを取得foodし、食物消費の結果を返します。

次に、各動物でこのメソッドを呼び出し、そこにあるすべての食べ物 (配列全体) を入れて、動物に何を食べるか、何を食べないかを決定させ、XXXFed、XXXNotFed などの適切な結果を返すことができます。など

ここで避けてほしいのは、型名を操作したり、大量の「if」を使用したりすることです。原型を作るにも汚すぎる。責任と懸念について考えてください。それが、とにかくそもそもOOPを持っている理由です:)

于 2013-03-10T10:18:50.087 に答える