14

私は最近、ラムダ式の調査を開始しましたが、疑問が頭に浮かびました。不確定な数のパラメーターを必要とする関数があるとします。params キーワードを使用して、可変数のパラメーターをモデル化します。

私の質問: ラムダ式で同様のことを行うことはできますか? 例えば:

Func<int[], int> foo = (params numbers[]) =>
                       {
                           int result;

                           foreach(int number in numbers)
                           {
                               result += numbers;
                           }

                           return result;
                       }

もしそうなら、2 つのサブ質問が提示されます - そのような式を書くための「良い」方法はありますか? また、ある時点でこのような式を書きたいと思いますか?

4

3 に答える 3

18

そうですね。まず、 を使用する代わりにFunc<>、カスタム デリゲートを定義する必要があります。

public delegate int ParamsFunc (params int[] numbers);

次に、次のラムダを記述できます。

ParamsFunc sum = p => p.Sum();

そして、可変数の引数で呼び出します:

Console.WriteLine(sum(1, 2, 3));
Console.WriteLine(sum(1, 2, 3, 4));
Console.WriteLine(sum(1, 2, 3, 4, 5));

Func<>しかし正直なところ、組み込みのデリゲートを使用する方がはるかに簡単です。

于 2012-06-26T20:13:23.883 に答える
3

あなたが得ることができると私が思う最も近いものは、次のようなものになるでしょう:

Func<int[], int> foo = numbers[] =>
                       {
                           // logic...
                       }

var result = foo(Params.Get(1, 5, 4, 4, 36, 321, 21, 2, 0, -4));

そして持っています:

public static class Params
{
    public static T[] Get(params T[] arr)
    {
        return arr;
    }
}

しかし、それが単純なものに勝る方法がわかりませんnew[] {1, 5, 4, 4, ...}

于 2012-06-26T20:08:15.857 に答える
1

ここにはFunc<int[], int>、LHS のジェネリック デリゲートと RHS のラムダ式の 2 つがあります。Func<S, T>デリゲートは次のように宣言されているため、前者は不可能です。

public delegate TResult Func<in T, out TResult>(T arg); //ie no params involved

params受け入れられた回答に示されているように、入力を受け入れる独自のデリゲートが必要です。

質問のタイトルが何であるかである後者は、C#でも同様に可能ではありませんが、理由があります。

代入式の LHS はコンパイル時のものであり (dynamicもちろんコンパイラがそれを認識している場合を除きます)、その RHS は実行時のものです (もちろんconsts の場合を除きます)。コンパイラは LHS で入力されたものを推測できますが、RHS では実行時、つまりコードの実行時にのみ値を取得します。これを入力すると:

Func<int[], int> foo = ....

fooは常に と見なされFunc<int[], int>ます。RHS を解読する必要がある場合、コンパイラに多くの複雑さが追加されます。たとえば、あなたが試みていることが可能だった場合、次のシナリオについて考えてみてください。

Func<int[], int> foo = (params int[] numbers) =>
                   {
                       int result;

                       foreach(int number in numbers)
                       {
                           result += numbers;
                       }

                       return result;
                   };

//and later at some other place
foo = (int[] numbers) => 0;

//how would you call 'foo' now?

代わりに、を受け入れる独自のデリゲートを作成するparamsと、コンパイラに直接伝えます (つまり、LHS から知られています)

名前付きメソッドのパラメーターがサポートする 3 つの機能、つまりout/ref、、paramsオプションのパラメーターのうち、ラムダ式 (または以前のdelegate構文でさえも) のみをサポートしますout/ref

于 2013-12-22T03:45:49.053 に答える