web-dev-qa-db-ja.com

Func <string、string>とデリゲートの違いは何ですか?

デリゲートは2つの形式で表示されます。

A. Func<string, string> convertMethod = lambda 

B. public delegate string convertMethod(string value);

これら2つの違いが実際に何であるかはわかりません。彼らは両方とも代理人ですか?最初のものはラムダを使用し、2番目のものは実際に作業を実行する方法を持たなければならないと思います。私も混乱するかもしれません。

64
Dietpixel

まず、あなたの2つの例は、2つのまったく別のことをしています。 1つ目は汎用デリゲート変数を宣言して値を割り当てることで、2つ目はdelegate型を定義することです。あなたの例は、より完全に、次のようになります:

_public static class Program
{
    // you can define your own delegate for a Nice meaningful name, but the
    // generic delegates (Func, Action, Predicate) are all defined already
    public delegate string ConvertedMethod(string value);

    public static void Main()
    {
        // both work fine for taking methods, lambdas, etc.
        Func<string, string> convertedMethod = s => s + ", Hello!";
        ConvertedMethod convertedMethod2 = s => s + ", Hello!";
    }
}
_

しかし、さらに重要なのは、_Func<string,string>_とdelegate string convertMethod(string)の両方が、メソッド、匿名メソッド、ラムダ式のいずれであっても、同じメソッド定義を保持できることです。

どちらを使用すべきかは、状況によって異なります。デリゲートを取得して返すものによってさらに定義したい場合、汎用デリゲートは完璧です。デリゲートに特別な名前を付けて、そのデリゲートが行うべきことをより簡単に定義したい場合(単純なActionPredicateなど)、独自のデリゲートを作成することは常にオプションです。

61

あなたが持っているコードサンプルは少し物事を混乱させているので、私はそれを試してみて、それをクリアしてみましょう。次の2つの項目はデリゲート宣言です。これらは常にdelegateキーワードを含むため、簡単に見つけることができます

public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);

このコード行は、デリゲートに入力されるローカルに値を割り当てています

Func<string, string> local = lambda;

上記のコードは、ラムダだけを使用することに限定されません。値は、互換性のあるメソッドグループまたは別のデリゲート値にすることもできます。

注意すべきもう1つの項目は、Func<string, string>convertMethodは両方とも同じシグネチャを持つデリゲートであり、それらの値はnot相互に変換可能です。たとえば、次は違法です

Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!
12
JaredPar

[〜#〜] msdn [〜#〜] から、

2.0以前のC#のバージョンでは、デリゲートを宣言する唯一の方法は、名前付きメソッドを使用することでした。 C#2.0は匿名メソッドを導入し、C#3.0以降では、ラムダ式がインラインコードを記述するための優先的な方法として匿名メソッドに優先します。

そして

無名メソッドがラムダ式にない機能を提供する場合が1つあります。匿名メソッドを使用すると、パラメーターリストを省略できます。これは、匿名メソッドをさまざまな署名を持つデリゲートに変換できることを意味します。

また、これに興味があるかもしれませんSO answer on デリゲートキーワードvsラムダ式

さらに、MSDNには Lambda Expressionsに関する良い記事 :があります。

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

前の例では、デリゲートシグネチャに、int型の暗黙的に型指定された入力パラメーターが1つあり、intを返すことに注意してください。ラムダ式は、1つの入力パラメーター(x)とコンパイラーが暗黙的にint型に変換できる戻り値も持っているため、その型のデリゲートに変換できます。 (型推論については、次のセクションで詳しく説明します。)5の入力パラメーターを使用してデリゲートを呼び出すと、25の結果が返されます。

8
user195488

[〜#〜] a [〜#〜]は、デリゲートのインスタンスを初期化します(すぐに呼び出すことができます)。 Func <string、string>型の変数です。

[〜#〜] b [〜#〜]は、デリゲート(その署名)の定義を指定します。タイプconvertMethodの変数を後で定義するために使用できます。

4
fparadis2