web-dev-qa-db-ja.com

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

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

  • 述語
  • アクション
  • ファンク

C#開発者が認識すべき他のデリゲートは何ですか?

本番コードでどれくらいの頻度で使用しますか?

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

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

  • Func:LINQでextensivelyを使用します。通常は引数を変換します。複雑な構造を1つのプロパティに投影します。

その他の重要な代表者:

  • EventHandler/EventHandler<T>:WinForms全体で使用

  • Comparison<T>IComparer<T>ただし、デリゲート形式。

177
Jon Skeet

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

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

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

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

36
Rahul Garg

ジョンの答えに加えて、

  • Converter<TInput, TOutput>:本質的にはFunc<TInput, TOutput>、ただしセマンティクス付き。 List.ConvertAllとArray.ConvertAllによって使用されますが、個人的には他のどこにも見られません。
9
G-Wiz

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

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

また、ThreadStartとParameterizedThreadStartにも注意してください。繰り返しますが、最近ではほとんどの人がアクションの代わりになります。

4
El Zorko

他の人はすでに特定のデリゲートの正しい使用法について言及していますが、私は彼らの答えを完成させる何かを追加したいと思います。 Func、Action、Predicateという名前には数学的な背景があります。物事を簡単にするために、次のような数学関数の非公式の定義を示します。

関数は、セット間の関係です。 1つのセットのメンバーを取得し、それを入力として使用すると、関数はこの入力を他のセットの1つのメンバーのみにマッピングします。つまり、何かが入力を取得し、出力を生成します。

繰り返しますが、非公式には、数学的な述語は、変数に応じてtrueまたはfalseになる可能性のあるステートメントです。他の人がブール値を返す関数に言及したように。

そして最後に、Actionはvoid関数(またはより数学的に正しい名前-voidメソッドまたはプロシージャ)です

3
Christian Rizov

述語、関数、およびアクションは、.NETの組み込みデリゲートインスタンスです。これらの各デリゲートインスタンスは、特定の署名を持つユーザーメソッドを参照または指すことができます。

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

Funcデリゲート-Funcデリゲートインスタンスは、可変数の引数を取り、何らかの型を返すメソッドを指すことができます。

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

3

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

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
user7917367

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
1
Rm558

引数に関する簡単な例と、各タイプが何を返すか

この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
1
dimath