web-dev-qa-db-ja.com

機能対アクション対述語

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

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

FuncActionの違いは、デリゲートが値を返す(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よりも頻繁に使用しますが、私はdoControl.BeginInvokeDispatcher.BeginInvoke

Predicateは、特別なケースFunc<T, bool>であり、FuncおよびほとんどのActionデリゲートのすべてが登場する前に導入されました。すでにFuncActionをさまざまな形で持っていたら、Predicateは導入されなかったのではないかと思います... doesはデリゲートの使用に特定の意味を与えますが、FuncActionは広く異なる目的に使用されます。

Predicateは、FindAllRemoveAllなどのメソッドのList<T>で主に使用されます。

869
Jon Skeet

Action はメソッドへのデリゲート(ポインタ)であり、ゼロ、1つ以上の入力パラメータを取りますが、何も返しません。

Func はメソッドへのデリゲート(ポインタ)で、ゼロ、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;
    }
}
335
Knasterbax

Func - あなたは、パラメータを取り、取り得ないかもしれない値を返す関数のデリゲートが欲しいとき。最も一般的な例は、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が適合する状況である。

61
Justin Niessner