2

私はここでジョン・スキートの答えを読んでいました

彼のサンプルの1つは:

  static void Main()
    {
        int x = 0;
        Foo( delegate { return x; } );
    }

    static void Foo(Func<int, int> action)
    {
        Console.WriteLine("I suspect the anonymous method...");
    }

しかし、どのようにFoo(Func<int, int>)対処することができdelegate { return x; }ますFunc<int>か?

実際のところ、Func< int,int,int,int,...>対処することもできdelegate { return x; }ます...

質問1 この動作の説明はありますか?

質問2

私はこのコードを持っています:

class MyClass
{
    public delegate void MyEventHandler(object sender);
    public  event MyEventHandler MyEvent;
}

そして私はジェネリックハンドラーを使いたかったので:

class MyClass
{
    public  Action<object> MyEventHandler;
    public  event MyEventHandler MyEvent;
}

しかし、私はこのエラーを受け取ります:

'UserQuery.MyClass.MyEventHandler(object)'は'メソッド'ですが、'タイプ'のように使用されます

なぜそれを認識しないのですか?

4

1 に答える 1

8

最初の質問に対する答えは、デリゲートへの引数はコンパイラーによって推測されるということです。int引数としてを取り、それに対して何もしない匿名メソッドがコンパイルされます。コードは次のように記述できます。

Foo( delegate (int dummy) { return x; } );

パラメーター・リストを省略することにより、現在のコンテキストのデリゲート型と同じ引数型を持つメソッドを発行するようにコンパイラーに指示します。コンパイラはaFunc<int, int>が予期されていることを認識しているため、匿名メソッドの引数タイプを一致させることができます。

言い換えるdelegate { ... }と、コンパイラに「匿名メソッドを作成しますが、引数を使用しないので引数が何であるかは気にしないので、このコンテキストでこのデリゲートを受け入れられるようにする引数を発行します」と指示します。(これは、「引数をとらない匿名メソッドを作成する」という意味とは異なりdelegate () { ... }ます。括弧に注意してください。これらの括弧をサンプルコードに追加すると、実際にコンパイルに失敗します。)

2番目のケースでは、タイプ名が必要なフィールド名を使用しています。フィールドを定義しても、フィールドの名前で型は作成されません。最初の例は正しいです。その場合、MyEventHandlerはタイプであり、フィールドではありません。(それが機能したとしても、最終的なデリゲート署名はコンパイル時にすでに決定されているため、ジェネリックを使用することは実際には役に立ちません。ジェネリックを使用することによる正味の利点はありません。)

于 2012-11-10T20:54:27.703 に答える