デリゲート:述語vsアクションvs関数


137

誰かがこれらの3つの最も重要なデリゲートの良い説明(できれば例)を提供できますか?

  • 述語
  • アクション
  • Func

回答:


180
  • Predicate:基本的にFunc<T, bool>; 「指定された引数はデリゲートによって表される条件を満たすか?」という質問をします List.FindAllなどで使用されます。

  • Action:引数を指定してアクションを実行します。非常に一般的な目的。LINQでは基本的に副作用を伴うため、あまり使用されません。

  • Func:LINQで広く使用れており、通常、たとえば、複雑な構造を1つのプロパティに投影することによって、引数を変換します。

その他の重要な代表者:

  • EventHandler/ EventHandler<T>:WinForms全体で使用されます

  • Comparison<T>:似てIComparer<T>いますが、デリゲート形式です。


3
System.Converter<TInput, TOutput>めったに使用されませんが、もあります。
G-Wiz

4
Converterはビジネスクラスにモデルの変換の多くが必要とされている素敵なデリゲートである、すなわちstum.de/2009/12/23/...
マイケルStum

EventHandler/EventHandler<T>WinFormsの外側にも表示されます。
アンディ

@Andy:やや...しかし、たとえばWPFではそれほどではありません。WinForms固有のものは何もないことに同意します。
Jon Skeet

48

ActionFuncおよびPredicateすべてがデリゲートファミリに属しています。

Action :アクションはn個の入力パラメーターを取ることができますが、voidを返します。

Func:Funcはn個の入力パラメーターを取ることができますが、常に指定されたタイプの結果を返します。Func<T1,T2,T3,TResult>ここで、T1、T2、T3は入力パラメーターで、TResultはその出力です。

Predicate:述語もFuncの形式ですが、常にboolを返します。簡単に言えばのラッパーですFunc<T,bool>


私はこの質問に関して今までに発見したベストと最も簡単な答え
Reyan Chougle

@ReyanChougle:うれしい、あなたはそれが役に立ったと思います。
Rahul Garg

9

ジョンの答えに加えて、

  • Converter<TInput, TOutput>:本質的にFunc<TInput, TOutput>はですが、セマンティクスがあります。List.ConvertAllとArray.ConvertAllで使用されますが、個人的には他のどこでも見たことはありません。

4

MethodInvokerは、WinForms開発者が使用できるものです。引数を受け入れず、結果を返しません。これはActionより前のバージョンであり、BeginInvoke()などが型指定されていないデリゲートを受け入れるため、UIスレッドを呼び出すときに引き続き使用されます。アクションも同様に行いますが。

myForm.BeginInvoke((MethodInvoker)delegate
{
  MessageBox.Show("Hello, world...");
});

ThreadStartとParameterizedThreadStartについても知っています。繰り返しになりますが、最近ではほとんどの人がアクションを代用します。


3

Predicate、Func、およびActionは、.NETの組み込みデリゲートインスタンスです。これらのデリゲートインスタンスはそれぞれ、特定の署名を持つユーザーメソッドを参照またはポイントできます。

アクションデリゲート-アクションデリゲートインスタンスは、引数を取り、voidを返すメソッドを指すことができます。

Funcデリゲート-Funcデリゲートインスタンスは、可変数の引数を取り、いくつかの型を返すメソッドをポイントできます。

述語-述語はfuncデリゲートインスタンスに似ており、可変数の引数を取り、ブール型を返すメソッドを指すことができます。


2

ラムダを使用したアクションと機能:

person p = new person();
Action<int, int> mydel = p.add;       /*(int a, int b) => { Console.WriteLine(a + b); };*/
Func<string, string> mydel1 = p.conc; /*(string s) => { return "hello" + s; };*/
mydel(2, 3);
string s1=  mydel1(" Akhil");
Console.WriteLine(s1);
Console.ReadLine();

2

FuncはよりLINQフレンドリーで、パラメーターとして渡すことができます。(ポイントフリー)

述語はできません。再度ラップする必要があります。

Predicate<int> IsPositivePred = i => i > 0;
Func<int,bool> IsPositiveFunc = i => i > 0;

new []{2,-4}.Where(i=>IsPositivePred(i)); //Wrap again

new []{2,-4}.Where(IsPositivePred);  //Compile Error
new []{2,-4}.Where(IsPositiveFunc);  //Func as Parameter

2

引数に関する簡単な例と、各型を戻す方法

このFuncは2つのint引数を取り、intを返します。Funcは常に戻り値の型を持っています

 Func<int, int, int> sum = (a, b) => a + b;
 Console.WriteLine(sum(3, 5));//Print 8

この場合、funcには引数はありませんが文字列を返します

Func<string> print = () => "Hello world";
Console.WriteLine(print());//Print Hello world

このアクションは2つのint引数を取り、voidを返します

Action<int, int> displayInput = (x, y) => Console.WriteLine("First number is :" + x + " , Second number is "+ y);
displayInput(4, 6); //Print First number is :4 , Second number is :6

この述語は1つの引数を取り、常にboolを返します。一般に、述語は常にboolを返します。

Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.