635

この質問にはすでに答えがあります。

実際の例とその使用法で、誰かが私を理解するのを手伝ってください。

  1. いつFuncデリゲートが必要ですか?
  2. Action代理人はいつ必要になりますか?
  3. Predicatesデリゲートはいつ必要になりますか?


  • これは重複していますが、より徹底的に受け入れられた答えがあります - reggaeguitar
  • @reggaeguitar面白いのは、どちらもJon Skeetからの回答です。 - rafid059

3 답변


810

違いはFuncそしてAction単にデリゲートに値を返させるかどうかです(使用Func)またはしない(使用)Action

Funcおそらく最も一般的にLINQで使用されています - 例えば、プロジェクションでは:

 list.Select(x => x.SomeProperty)

またはフィルタリング:

 list.Where(x => x.SomeValue == someOtherValue)

またはキーの選択

 list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)

Actionのようなものにもっと一般的に使われていますList<T>.ForEach:リスト内の各項目に対して与えられたアクションを実行します。私はこれをあまり使わないFunc、私は行う時々のようなもののためにパラメータのないバージョンを使用するControl.BeginInvokeそしてDispatcher.BeginInvoke

Predicate特別なケースですFunc<T, bool>実際には、FuncそしてほとんどのAction参加者がやってきた。私たちがすでに持っていたならば、私は疑うFuncそしてActionさまざまな装いでPredicate導入されなかったでしょう…それがするデリゲートの使用に一定の意味を与えるFuncそしてAction広く異なる目的で使用されています。

Predicate主に使用されていますList<T>のようなメソッドFindAllそしてRemoveAll


  • 見るのが好きPredicate関数シグネチャ内渡されたメソッドが単に成功コードや別の種類のコードを返すのではなく、決定を下すことを示しています。bool。 - Ron Warholic
  • 好むかどうかについての設計ガイドラインはありますかPredicate<T>またはFunc<T,bool>?の表現力が好きPredicateの推奨事項を確認しましたFuncも。 - CodesInChaos
  • @ロン:はい、それは私の最後から2番目の段落についてのものです。 - Jon Skeet
  • @CodeInChaos:私が見たことはありません。 LINQの用途Funcしかし、これは一貫性を保つためのものです。Func<T,bool>述語としても過負荷を取っているFunc<T,int,bool>インデックス付き述語の場合。 - Jon Skeet
  • 説明が簡単なようです。 func - アクションを返す - 実行する(メソッド) - Juvil

322

アクションメソッドへのデリゲート(ポインタ)です。これは、0個、1個以上の入力パラメータを取りますが、何も返しません。

機能メソッドへのデリゲート(ポインタ)です。ゼロ、1つ以上の入力パラメータを取り、値(または参照)を返します。

述語比較によく使われる特別な種類のFuncです。

ActionやFuncは、Linqで広く使われていますが、Linqから論理的に独立した概念です。 C ++はすでに型付き関数ポインタの形で基本概念を含んでいました。

これは、Linqを使わないでのActionとFuncの小さな例です。

class Program
{
    static void Main(string[] args)
    {
        Action<int> myAction = new Action<int>(DoSomething);
        myAction(123);           // Prints out "123"
                                 // can be also called as myAction.Invoke(123);

        Func<int, double> myFunc = new Func<int, double>(CalculateSomething);
        Console.WriteLine(myFunc(5));   // Prints out "2.5"
    }

    static void DoSomething(int i)
    {
        Console.WriteLine(i);
    }

    static double CalculateSomething(int i)
    {
        return (double)i/2;
    }
}


  • 述語は、一般的なパラメータを取り、ブール値を返すデリゲートです。 - Martin
  • いい例です。 myActionを呼び出すだけで呼び出すこともできます。myAction(123);。使用する必要はありません.Invoke() - romar
  • パラメータをとらずに値(または参照)を返すFuncを使いたい場合は、完全を期すために、次のように書く必要があります。FUNC< double> myFoo = new Func< double>(foo);そしてfooの定義はstatic double foo(){return 1.0;} - A.B.

58

機能 - パラメータを取り込むかどうかにかかわらず、値を返す関数のデリゲートが必要な場合。最も一般的な例は、Select from LINQです。

var result = someCollection.Select( x => new { x.Name, x.Address });

アクション - パラメータを使用する場合と使用しない場合があり、値を返さない関数のデリゲートが必要な場合。私は匿名のイベントハンドラにこれらを頻繁に使用します。

button1.Click += (sender, e) => { /* Do Some Work */ }

述語 - 一連の基準に対して値を評価し、ブール値の結果を返す特殊なバージョンのFuncが必要な場合(一致した場合はtrue、それ以外の場合はfalse)。繰り返しになりますが、これらはLINQで、次のような目的で頻繁に使用されています。

var filteredResults = 
    someCollection.Where(x => x.someCriteriaHolder == someCriteria);

二重チェックしたところ、LINQは述語を使用していません。なぜ彼らがその決断をしたのかわからない…でも理論的にはそれでもPredicateが当てはまる状況である。


  • 私はこれが古いことを知っていますが、Predicateは今日我々が知っているFuncとActionより前にあるのでLINQでは使われませんでした、そして後者の2つはずっと良い方法でまったく同じ結果を達成するために使われることができます。 - gparent
  • @親、なぜそれが優れているのですか?意味のある名前のデリゲートを使う代わりに読みやすさが良いと思いますFuncまたはAction。 - Sam
  • デリゲートの使い方によって異なりますが、名前がそれほど重要ではなく、1回だけ使用するために関数や変数を作成しなければならない場合があるため、読みやすさが低下します。 - gparent

リンクされた質問


関連する質問

最近の質問