Как Типизация делегата / лямбда и принуждение работают?

Я заметил несколько примеров того, что работает и не работает при работе с лямбда-функциями и анонимными делегатами в C #. Что здесь происходит?

class Test : Control {
    void testInvoke() {
        // The best overloaded method match for 'Invoke' has some invalid arguments
        Invoke(doSomething);

        // Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type
        Invoke(delegate { doSomething(); });

        // OK
        Invoke((Action)doSomething);

        // OK
        Invoke((Action)delegate { doSomething(); });

        // Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type
        Invoke(() => doSomething());

        // OK
        Invoke((Action)(() => doSomething()));
    }

    void testQueueUserWorkItem() {
        // The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments
        ThreadPool.QueueUserWorkItem(doSomething);

        // OK
        ThreadPool.QueueUserWorkItem(delegate { doSomething(); });

        // The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments
        ThreadPool.QueueUserWorkItem((Action)doSomething);

        // No overload for 'doSomething' matches delegate 'WaitCallback'
        ThreadPool.QueueUserWorkItem((WaitCallback)doSomething);

        // OK
        ThreadPool.QueueUserWorkItem((WaitCallback)delegate { doSomething(); });

        // Delegate 'WaitCallback' does not take '0' arguments
        ThreadPool.QueueUserWorkItem(() => doSomething());

        // OK
        ThreadPool.QueueUserWorkItem(state => doSomething());
    }

    void doSomething() {
        // ...
    }
}

Ну, это много примеров. Думаю, у меня следующие вопросы:

  1. Почему Invoke всегда отклоняет лямбда-функцию или анонимный делегат, а ThreadPool.QueueUserWorkItem отлично справляется?

  2. Что за фигня все равно означает «Невозможно преобразовать анонимный метод в тип System.Delegate, потому что это не тип делегата»?

  3. Почему ThreadPool.QueueUserWorkItem принимает анонимный делегат без параметров, но не лямбда выражение без параметров?

9
задан Ani 29 September 2010 в 14:24
поделиться