Zauważyłem kilka przykładów rzeczy, które działają i nie działają podczas pracy z funkcjami lambda i anonimowymi delegatami w języku C#. Co tu się dzieje?Jak działają typing delikates/lambda i koercja?
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() {
// ...
}
}
Cóż, to dużo przykładów. Chyba moje pytania są następujące:
Dlaczego
Invoke
zawsze odmówić funkcję lambda lub anonimowy delegata, jeszczeThreadPool.QueueUserWorkItem
robi dobrze?Co do cholery robi "Nie można przekonwertować metody anonimowej do typu" System.Delegate ", ponieważ nie jest to typ delegata" oznacza tak?
Dlaczego
ThreadPool.QueueUserWorkItem
akceptuje anonimowy delegat bez parametrów, ale bez wyrażenia lambda bez parametrów?
I pomyślałem, zrozumiałem delegatów i lambdy. Byłem tak głupi. – recursive
Dobra rzecz jak zawsze, +1 dla "... jest jedyną cechą jaką mają wyrażenia lambda". – Ani
@recursive, jeśli chcesz dowiedzieć się więcej, przeczytaj o drzewach wyrażeń. Interesującą rzeczą w wyrażeniach lambda jest to, że naprawdę są one _expressions_, z bogatym opisowym modelem tego, co jest wyrażane, a nie tylko syntaktycznym skrótem dla przekazywania logiki do parametru delegata. To właśnie pozwala magii, takiej jak LINQ, na SQL. http://msdn.microsoft.com/en-us/library/bb397951.aspx –