5

私の最初の(そして本当に恐ろしい投稿)は以下です。

私が得たいものの完全な例をやろうとしています。これがもう少しよく説明されたままになることを願っています。

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Boy> boys = new List<Boy>();
            boys.Add(new Boy("Jhon", 7));
            boys.Add(new Boy("Oscar", 6));
            boys.Add(new Boy("Oscar", 7));
            boys.Add(new Boy("Peter", 5));
            ClassRoom myClass = new ClassRoom(boys);

            Console.WriteLine(myClass.ByName("Oscar").Count);  // Prints 2
            Console.WriteLine(myClass.ByYearsOld(7).Count);  // Prints 2

            // This has errors...................
            // But this is as I would like to call my BySomeConditions method....
            Console.WriteLine(  // It should print 1
                                myClass.BySomeConditions([myClass.ByName("Oscar"),
                                                          myClass.ByYearsOld(7)]
                                                        )
                             );
            Console.ReadKey();
        }





        class ClassRoom
        {
            private List<Boy> students;

            public ClassRoom(List<Boy> students)
            {
                this.students = students;
            }

            public List<Boy> ByName(string name)
            {
                return students.FindAll(x => x.Name == name);
            }
            public List<Boy> ByYearsOld(int yearsOld)
            {
                return students.FindAll(x => x.YearsOld == yearsOld);
            }

            // This has ERRORS.......................
            public List<Boy> BySomeConditions(params Func<X, List<Boy>>[] conditions)
            {
                IEnumerable<Boy> result = students;                
                foreach (var condition in conditions) {
                    // I want it ONLY be called with existent functions (ByName and/or ByYearsOld)
                    result = result.Intersect(condition(this));  
                }
            }
        }


        class Boy
        {
            public string Name { get; set; }
            public int YearsOld { get; set; }
            public Boy(string name, int yearsOld)
            {
                Name = name;
                YearsOld = yearsOld;
            }
        }
    }
}

============== 初投稿 ==================== こんにちは。

私はメソッドを持つクラスを持っています:

public class X
{
    private readonly List<string> myList;

    public X(List<string> paramList) // string is really an object
    {
         myList = paramList;
    }

    // Now I want this...
    public List<string> CheckConditions(params Func<T, List<string>>[] conditions)
    {
         var result = myList;
         foreach (Func<T, List<string>> condition in conditions)
         {
               result = result.Intersect(condition(T));
         }
    }

    public List<string> check1(string S)
    {
         return myList.FindAll(x => x.FieldS == S);
    }
    public List<string> check1(int I)
    {
         return myList.FindAll(x => x.FieldI == I);
    }
}

エラーがある場合は申し訳ありませんが、複雑な実際のケースを避けるためにゼロから書いています。

私が欲しいのは、次のようにメソッドを呼び出すことです:

   X.check1("Jhon");

また

   X.check2(12);

または(これが私の質問の目標です):

   X.CheckConditions(X.check1("Jhon"), X.chek2(12));

私の悪い例で感謝し、申し訳ありません...

4

5 に答える 5

3

あなたのTがどこから来たのかは不明です。

これはあなたの要件を満たしていますか?

public class X<T>
{
  private List<T> myList;

  public List<T> CheckConditions(params Func<T, bool>[] conditions)
  {
    IEnumerable<T> query = myList;
    foreach (Func<T, bool> condition in conditions)
    {
      query = query.Where(condition);
    }
    return query.ToList();
  }
}

じゃあ後で:

List<T> result = X.CheckConditions(
  z => z.FieldS == "Jhon",
  z => z.FieldI == 12
);
于 2011-03-11T20:54:16.337 に答える
2

のメソッド シグネチャを変更する必要があります。関数ではなくCheckConditions、可変数の を受け入れてList<string>います。

public List<string> CheckConditions(params List<string>[] lists)

の戻り値の型check1はであるため、受け入れるList<string>パラメーターの型である必要があります。CheckConditions

于 2011-03-11T20:44:33.423 に答える
1

の現在のインスタンスを操作したいことがわかっているため、ジェネリックにする理由はありません(型パラメーターの代わりに をX渡します)。コンパイルするには、いくつかのことをクリーンアップする必要があります (戻り、型と呼び出しに互換性を持たせます)。次のように定義できます。thisTresultresultIntersect

public List<string> CheckConditions(params Func<X, List<string>>[] conditions)
{
     IEnumerable<string> result = myList;
     foreach (var condition in conditions)
     {
           result = result.Intersect(condition(this));
     }

     return result.ToList();
}

Ant は次のように呼び出します。

xInstance.CheckConditions(x => x.check1("JHon"), x => x.check1(12));

そうは言っても、実際の関数を渡すのではなく、これらの関数の結果だけを渡さない理由がわかりません。

public List<string> CheckConditions(params List<string>[] conditions)
{
     IEnumerable<string> result = myList;
     foreach (var condition in conditions)
     {
           result = result.Intersect(condition);
     }

     return result.ToList();
}

次に、ラムダ式を渡すのではなく、例のように呼び出します。

于 2011-03-11T20:49:34.260 に答える
0

あなたがあなたに渡すもの

X.CheckConditions

関数への参照ではなく、呼び出しの戻り値です。

ここで、関数参照を渡す場合、関数参照とそれが機能する引数を含むデータ構造を構築して渡さない限り、パラメーターは付属しません。

この場合、ジェネリックは解決策ではありません。コマンドパターンや戦略パターンなど、CheckConstructionチェッカーオブジェクトのインスタンスに渡す別のパターンに従うことを検討する必要があります。各パターンは、動作するパラメーターでインスタンス化され、検証関数によって実装または提供されます。

于 2011-03-11T20:44:28.320 に答える
0

関数を次のように書き直すことができます。

// Now I want this...
    public List<string> CheckConditions(params Func<T, List<string>>[] conditions)
    {
         var result = myList;
         foreach (Func<T, List<string>> condition in conditions)
         {
               result = result.Intersect(condition(T));
         }
    }

あなたの呼び出しはX.CheckConditions(()=>X.check1("Jhon"), ()=>X.chek2(12));

xのインスタンスを提供する必要があります(メソッドはインスタンスメソッドであり、静的メソッドではないため)

あなたの例では、 T を引数としてファンクターに渡しますが、 T は型引数であるため、メソッドに引数として渡すことはできません。値を渡すつもりでしたか?

これは、なぜこれを行いたいのかを明確にすることを求めています。(方法ではなく) 何を達成しようとしているのかについて詳細を提供していただければ、問題に対するより良い解決策を得ることができるかもしれません。

于 2011-03-11T20:47:16.107 に答える