Lambda expression is clearer than the combination of definition and Out-of-band method definitions, and the additional work involved is only required to satisfy the language definition. However, it also has some deficiencies. If the parameter of a method contains an abstract type such as System.Delegate, a lambda expression is used to introduce the special problem: The C # compiler cannot convert a lambda expression to a derived representative type that is not yet explicitly defined.
If you don't think about it, your code will look like it's coming from. NET1.0 of things. In this article, I'll tell you why a lambda expression is not enough to be directly converted to an abstract representative type, and teach you how to make the compiler convert the specified delegate you define. The solution relies on Windows presentation Foundation (WPF) and System.Windows.Threading.Dispatcher components, but the issue is not strictly a WPF issue in the strictest sense. The problems described in the article appear in several. NET Framework, including the Windows Forms,office application interface and the mapping application interface. You can deal with similar problems according to the following methods.
No matter when I use. NET Framework, I would prefer to use a lambda expression instead of a more detailed expression, with an application interface from a parameter representing a table. For example, this line of code creates a System.Windows.Threading.Timer that, when the timer fails, calls a Tickhandler method:
tick = new System.Threading.Timer((unused) =>
TickHandler());
If the content of the method is small enough, I will use the content of the method instead of the Tickhandler () method call. This method works in most cases, but this technique does not work when the application interface takes System.Delegate as a parameter. For example, we pass the System.Windows.Controls.Dispatcher.Invoke () method through a thread implementation call in WPF:
public object Invoke(
delegate method,
params object[] args)
Now consider what happens when we try to execute such a call with a lambda expression:
MyTime.Dispatcher.Invoke(() => DoSomething());
There will be a hidden error:
error CS1660: Cannot convert lambda expression to
type 'System.Delegate' because it is not a delegate type
Perhaps the first time you see this error, you still do not know what is going on. Of course, this is indeed a representative type. Compilers are not as flexible as people. The System.Delegate type is an abstract type and the inference tool of that type cannot infer the number and kind of the derived variable or some of the return values used for the unknown representative type. To resolve this problem, we must create a specific representative type and specify a lambda expression for that type. Remember, the representative type requires that you treat the method as data.
I created a WPF timer program to show how it works, and it explains how c#3.0 simplifies the operation of an older application interface (the following figure).
When you do the demo, the application in the example runs a timer, and as the set time passes, its color turns from green to yellow and then to red. This is a good demonstration of a method called across threads because the timer runs in the background thread.
Updating the demo according to the time change requires a response to events originating from the timer. The timer runs in the background thread, so you can easily make the mistake we mentioned earlier.