20

私はしばらくの間Func<>を使用してきましたが、(今のところ)それを回避することができました。しかし、今では永遠にかわすことができないようです。たとえば、Dynamic Linqを試しましたが、ほとんどすべてがFunc<>の観点からのものでした。私は自分の本の1つ(C#2008 / Deitel&Deitel)とMSDNも試しましたが、まだ入手できていません。それらはすべて主題にまっすぐジャンプします。

  1. Func <>について(簡単に)言えること
  2. その問題に取り掛かることができるいくつかのリンクをWebで入手できますか?

助けてくれてありがとう

4

7 に答える 7

32

Func<>は一般的なデリゲートです。引数と戻り値のタイプの組み合わせごとに独自のデリゲートを作成する必要がないため、非常に便利です。
以前は、次のようなものを書く必要がありました。

public delegate long MyDelegate( int number );

public void Method( IEnumerable<int> list, MyDelegate myDelegate )
{
    foreach( var number in list )
    {
        myDelegate( number );
    }
}

ユーザーがメソッドを正しく呼び出すことができるように、デリゲートを公開する必要がありました。特に、多数の異なるデリゲートが必要な場合は、引数リストとリターンタイプごとに1つずつ公開することになります。あなたと一緒に書くだけです
Func<>

public void Method( IEnumerable<int> list, Func<int, long> myDelegate )
{
    foreach( var number in list )
    {
        myDelegate( number );
    }
}

これは、最初のコード例と同じ意味Func<int, long>です-1つの整数引数を取り、長い値を返すデリゲートを定義します。

もちろん、より長いパラメータリストを使用することもできます。2つのintbool値を使用している間も、長い値をFunc<int, int, bool, long>返します。戻り値のないデリゲートが必要な場合は、を使用する必要があります。これは、戻りタイプとしてvoidを持ちます。Action<>

編集(リクエストによる):私の例のメソッドを呼び出す方法

MyDelegate呼び出し元の場合、またはを使用したソリューションに違いはありませんFunc<>。どちらの場合も、メソッドを呼び出すための3つのオプションがあります。

ラムダ表記の使用(C#3.0が必要、おそらく短いメソッドに最適なソリューション):

Method( myList, i => i * i );

匿名メソッドを使用する(C#2.0が必要):

Method( myList, delegate( int i )
{
    return i * i;
} );

または、引数として実際のメソッドを使用することによって:

Method( myList, Square );

private static long Square( int number )
{
    return number * number;
}
于 2010-04-18T09:17:33.367 に答える
12

Func<...>デリゲート型のファミリーであり、いくつかの値を返し、いくつかの引数を取ります。例えば:

  • Func<int,bool>単にintを取り、boolを返すものです(戻りは常に最後にあります)。たとえば、述語:

    int[] data = {1,2,3,4,5};
    var odd = data.Where(i => i % 2 == 0);
    
  • Func<string>は、などの文字列を返すメソッドです() => "hello world";

  • Func<DateDtime, TimeSpan, DateTime>のようなものかもしれません(when,howLong) => when + howLong;

同様にAction<...>、同じことをしますが、リターンタイプがないものがあります。

魔法は何もありませんFunc<...>-デリゲートを表現するためのより簡単な方法ですが、a:ジェネリックス(LINQに便利)を使用するか、b:引数が何であるかを調べる必要はありません。デリゲートタイプがあいまいなものである場合(PipeStreamImpersonationWorkerたとえば)、それが何を必要とするかを知るのは難しい場合があります。それが比較可能なものとして表現された場合、Actionそれはパラメータをとらず、を返すことは明らかですvoid

于 2010-04-18T09:11:09.383 に答える
10

これは役立つかもしれません。あなたが自分自身に考えているのを見るたびに仮定Func<int, string>してください:

interface IFuncIntString
{
    string Invoke(int x);
}

つまり、デリゲートはこのインターフェイスを実装するオブジェクトです。これには、intを受け取り、文字列を返すInvokeという単一のメソッドがあります。

次に、通話の「呼び出し」を省略できる機能を追加すると、代理人ができます。

于 2010-04-18T15:29:56.630 に答える
7

Func<int>(たとえば)はタイプです(つまりstring、タイプです)。したがって、これを使用して、変数、フィールド、パラメーターなどを宣言します。

これは、答えを求めるたびに実行できる計算を表します。

Func<int> f = () => DateTime.Now.Second;

// elsewhere...

Console.WriteLine( f() );

メソッドのように呼び出す方法に注意してください。Funcさまざまな数のパラメーターをサポートするために、のオーバーロードされたバージョンが多数あります。最後の型引数は戻り型です。

Func<int, string> quoteInt = n => "\"" + n + "\"";

Console.WriteLine( quoteInt(3) );

Funcデリゲートタイプです。自分で宣言することもできますが、使用する方が簡単Funcです。戻りたい場合は、の代わりにをvoid使用してください。またはパラメータが必要な場合にのみ、カスタムデリゲートを宣言する必要があります。ActionFuncoutref

ラムダをに割り当てるときFuncは、ローカル変数を参照できます。これは非常に強力です。これは、aFuncが単なるコードではないことを意味します。データがあります。つまり、単一のメソッドを持つオブジェクトのようなものです(技術的には、メソッドが呼び出されInvoke、デリゲートを呼び出すときにコンパイラが暗黙的にそのメソッドを呼び出します)。

構文() =>は、「今はこれを行わないで、後で実行するまで遅らせる」という式の前に配置できます。これにより、遅延した計算をキャプチャするデリゲートを初期化できます。次に、デリゲートの後に構文()を配置して、実際に計算をトリガーできます。したがって、接尾辞()は一種です-接頭辞の反対です() =>

于 2010-04-18T09:14:18.583 に答える
3

101のLinqサンプルから始めることができます。

つまり、Func<>はデリゲートであり、最後のタイプパラメータはリターンタイプです。

したがって、はパラメータを受け取り、を返すFunc<int,bool>デリゲートです。intbool

于 2010-04-18T09:08:21.003 に答える
1

C#で=>演算子を使用したことがあり、おそらく使用している場合は、すでにFuncsを使用しています。あなたはそれらを明示的に宣言していないだけです。

だから、あなたが次のようなステートメントを書くなら

var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");

Func<Person, bool>Where()メソッドにを渡します。

言葉になりたい場合は、そのステートメントを次のように書き直すことができます。

Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue";
var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);

そして、同じ結果が得られます。

于 2010-04-18T16:38:59.333 に答える
1

Func <...、T>はデリゲートです。ここで、Tはreturn-typeであり、その他はすべて-入力パラメーターです。

于 2010-04-18T09:12:02.407 に答える