Funcの説明


89

私は誰かがFunc<int, string>それが何であるか、そしてそれがどのように使用されるかをいくつかの明確な例で説明できるかと思っていました。

回答:


145

デリゲートについて一般的に知っていますか?私はデリゲートとイベントについてのページを持っていますが、そうでない場合は役立つかもしれませんが、2つの違いを説明することを目的としています

Func<T, TResult>は単なる一般的なデリゲートです。宣言の型パラメーターTおよびTResult)を対応する型引数intおよびstring)で置き換えることにより、特定の状況での意味を理解してください。また、混乱を避けるために名前を変更しました。

string ExpandedFunc(int x)

つまり、Func<int, string>int引数を取り、を返す関数を表すデリゲートstringです。

Func<T, TResult>LINQでは、プロジェクションと述語の両方によく使用されます(後者の場合TResultは常にですbool)。たとえばFunc<int, string>、一連の整数を一連の文字列に射影するためにa を使用できます。ラムダ式は通常、関連するデリゲートを作成するためにLINQで使用されます。

Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);

foreach (string s in strings)
{
    Console.WriteLine(s);
}

結果:

Value=3
Value=7
Value=10

3
「言い換えれば、これはint引数を取り、文字列を返す関数を表すデリゲートです。」他の人の混乱を避けるために、ここではFunc <T、TResult>ではなく、Func <int、string>について話していることを明確にします。ジェネリック型とデリゲートを理解しているかどうかは明らかですが、理解できない人にとっては、int引数を取り、文字列を返す関数にデリゲートするのはFunc <int、string>です。
実際のナップスター

後でPCに戻ったときに明確になります。
ジョンスキート、

2
これは実際には、MSDNの説明や例ほど明確ではないと思います。最後の型paramが戻り値の型であるという情報も追加する必要があると思います。Func<int、int、string>が文字列を返し、2つの整数を取ることを明確にします。それは明確にするのに役立ちます。個人的なことは何もありません。十分に明確であるとは思いませんでした。
TheSoftwareJedi 2009年

11
それで、あなたはあなたの特定のお気に入りほど役に立たないと思われるすべての回答に反対票を投じますか?この回答は積極的に役に立たないと思いますか?おそらく、複数の見方をすることは悪い考えではないかもしれないと思いますか?
ジョンスキート、

8
@TheSoftwareJedi:もちろん、個人的にあなたの反対票を投じる理由はありません-あなた土曜日に個人的な理由で反対票を投じた後、適切な行動についてメールで長い議論をした後、たまたまこのスレッドに入りました。で完全に偶然、そうではありませんか?
ジョンスキート、

40

A Func<int, string>はintを食べ、文字列を返します。では、何がintを食べて文字列を返すのでしょうか?これはどう ...

public string IntAsString( int i )
{
  return i.ToString();
}

そこで、intを食べて文字列を返す関数を作成しました。どうやって使うの?

var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;

foreach( int i in lst )
{
  str += IntAsString(i);
}

// str will be "12345"

それほどセクシーではありませんが、それは多くのトリックが基づいている単純なアイデアです。では、代わりにFuncを使用しましょう。

Func<int, string> fnc = IntAsString;

foreach (int i in lst)
{
  str += fnc(i);
}

// str will be "1234512345" assuming we have same str as before

各メンバーでIntAsStringを呼び出す代わりに、fncという名前の参照を作成し(これらのメソッドへの参照はデリゲートと呼ばれます)、代わりにそれを使用しました。(fncはintを食べて文字列を返すことを思い出してください)。

この例はそれほどセクシーではありませんが、関数、デリゲート、および拡張メソッドの単純なアイデアに基づいた、見栄えの良いものはたくさんあります。

私が見た中でこれについての最高の入門書はここにあります。彼にはもっともっと実例があります。:)


@Therealnapster私も好きですが、あなたの名前がもっと好きです。
BKSpurgeon 2016年

27

これは、1つintをパラメーターとして取り、typeの値を返すデリゲートですstring

以下はその使用例です。

using System;

class Program
{
    static void Main()
    {
        Func<Int32, String> func = bar;

        // now I have a delegate which 
        // I can invoke or pass to other
        // methods.
        func(1);
    }

    static String bar(Int32 value)
    {
        return value.ToString();
    }
}

3
アンドリューありがとう。bar(1)の代わりにfunc(1)を書くつもりでしたか?
zSynopsis 2009年

1

Func<int, string>int valueパラメータを受け入れ、文字列値を返します。追加のサポート方法が不要な例を次に示します。

Func<int, string> GetDogMessage = dogAge =>
        {
            if (dogAge < 3) return "You have a puppy!";
            if (dogAge < 7) return "Strong adult dog!";

            return "Age is catching up with the dog!";
        };

string youngDogMessage = GetDogMessage(2);

注:Funcの最後のオブジェクトタイプ(この例では「string」)は、関数の戻り値のタイプです(つまり、プリミティブに限定されず、任意のオブジェクト)。したがって、Func<int, bool, float>intおよびbool値パラメーターを受け入れ、float値を返します。

Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
        {
            if(intValue > 100 && boolValue) return 100;

            return 1;
        };
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);

HTH

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.