10

LINQPad の例:

void Main()
{
    One(i => PrintInteger(i));
    One(PrintInteger);

    Two(i => PrintInteger(i));
    // Two(PrintInteger); - won't compile
}

static void One(Action<int> a)
{
    a(1);
}

static void Two(Expression<Action<int>> e)
{
    e.Compile()(2);
}

static void PrintInteger(int i)
{
    Console.WriteLine(i);
}

行のコメントを外すTwo(PrintInteger);と、エラーが発生します。

「メソッド グループ」から「System.Linq.Expressions.Expression<System.Action<int>>」に変換できません

これはConvert Method Group to Expressionに似ていますが、「なぜ」に興味があります。機能にはお金、時間、労力がかかることを理解しています。もっと面白い説明があるかどうか疑問に思っています。

4

3 に答える 3

3

原則として理由はありません。このように行うことができました。コンパイラは、ラムダを変換する前にそれ自体を作成することができます (これは明らかに常に可能です - 呼び出されている正確なメソッドを知っているので、そのパラメータからラムダを作成することができます)。

ただし、問題が 1 つあります。ラムダのパラメーターの名前は、通常、生成される IL にハードコードされています。ラムダがない場合、名前はありません。ただし、コンパイラは、ダミーの名前を作成するか、呼び出されるメソッドの名前を再利用することができます (.NET アセンブリ形式で常に使用できます)。

C# チームがこれを有効にしないのはなぜですか? 頭に浮かぶ唯一の理由は、彼らが他の場所で時間を過ごしたかったということです。彼らの決断に拍手を送ります。このあいまいな機能よりも、LINQ または async の方が好きです。

于 2013-04-07T18:45:47.667 に答える
0

このOne例では、Action<int>デリゲートを暗黙的に作成しています。以下と同じです:

One( new Action<int>( PrintInteger ) );

これは、イベントをサブスクライブするための構文を改善するための言語にあると思います。

では同じことが起こらないためExpression<T>、2 番目の例はコンパイルされません。


編集 :

これを「メソッド群変換」と呼びます。それはC#仕様にあります-セクション6.6

メソッド グループ (§7.1) から互換性のあるデリゲート型への暗黙的な変換 (§6.1) が存在する

于 2013-04-07T18:46:54.543 に答える