About Lambda expressions accessing external variables, lambda expression Variables

Source: Internet
Author: User

About Lambda expressions accessing external variables, lambda expression Variables

The book C # advanced programming mentions that using Lambda expressions to access external variables of Lambda expressions blocks is a good function (similar to closures in Js ). However, it is very dangerous to use it correctly.

For example

Int someVal = 5;

Fun <int, int> f = x => x + someVal;

Console. WriteLine (f (3 ));

Our expression is intended to return the result of a number x + 5. Therefore, the result of f (3) should be 3 + someVal = 8.

However, if someVal value is accidentally modified in the future, unexpected results will appear.

For example:

SomeVal = 7;

Console. WriteLine (f (3 ));

The printed result is 10.

Especially when Lambda is called through multiple threads, we may not know the value of someVal at this time, resulting in unpredictable results, so we should use it with caution.

 

So what is the principle of using external variables in Lambda expressions.

Originally, when running a Lambda expression, the compiler creates an anonymous class, which can pass external variables through constructors. The parameters of this constructor depend on the number of variables passed in externally. For the above expression, the anonymous class is as follows:

 

Public class AnonymousClass {

Private int someVal;

Public AnonymousClass (int someVal) {this. someVal = someVal ;}

Public int Anonymous (int x) {return x + someVal ;}

}

In this way, we can understand why Lambda expressions can use external variables.


How to Use Lambda expressions for abstract representation

However, it also has some shortcomings. If a method parameter contains an abstract type such as System. Delegate, use a lambda expression to introduce a special problem: the C # compiler cannot convert a lambda expression to a derivative representative type that has not yet been clearly defined. Without careful consideration, your code looks like something from. NET1.0. In this article, I will tell you why lambda expressions are insufficient to be directly converted to abstract representative types, and teach you how to make the compiler convert the specified representatives you define. The solution depends on the Windows Presentation Foundation (WPF) and System. Windows. Threading. Dispatcher components, but strictly speaking, this issue is not a WPF issue. The problems described in this article appear in several. NET frameworks, including Windows Forms, Office application interfaces, and ing application interfaces. You can solve similar problems in the following ways. Whenever I use an application interface with parameters representing tables in the. NET Framework, I tend to use lambda expressions instead of more detailed expressions. For example, this line of code creates a System. windows. threading. timer, when the Timer fails, the Code calls a TickHandler method: tick = new System. threading. timer (unused) => TickHandler (); If the content of the method is small enough, I will replace the TickHandler () method call with the content of the method. This method works in most cases, but this technique does not work when the application interface uses System. Delegate as a parameter. For example. windows. controls. dispatcher. the Invoke () method is called through a thread in WPF: public object Invoke (delegate method, params object [] args). Now, when we try to use a lambda expression to execute such a call, what will happen: MyTime. dispatcher. invoke () => DoSomething (); a hidden error occurs: error CS1660: Cannot convert lambda expression totype' System. delegate 'because it is not a delegate type. Maybe the first time you see this error, you still don't know what it is. Of course, this is indeed a representative type. Compilers are not as flexible as humans. The System. Delegate type is an abstract type. Reasoning tools of this type cannot infer the number and type of values returned by a derived variable or an unknown representative type. To solve this problem, we must create a specific representative type and specify a lambda expression for this type. Remember, the Representative type requires you to regard the method as data. I created a WPF Timer Program to demonstrate how it works. It explains how C #3.0 simplifies the running of interfaces with older applications. When you do the demo, the app in this example runs a timer. As the set time passes, the color of the timer changes from green to yellow and then red. This is a good way to demonstrate cross-thread calling, because the timer runs in the background thread. Update the demo Based on Time changes to respond to events from the timer. The timer runs in the background thread, so you will easily make the mistake we mentioned earlier. The updated application user interface processes simple code. It takes effect when the timer expires, and the code updates the timer display. This update must change the text or control the background. As shown in the following figure: MyTime. Background = newBrush; MyTime. Content = label timing ...... the remaining full text>

Where does the lambda expression come from?

Lambda Expressions (Lambda Expressions) 16: 33 Lambda Expressions (Lambda Expressions) and anonymous methods are actually one thing. The only difference is that their syntax format is different. Lambda expressions are further evolved in terms of syntax. In essence, they are one thing. Their role is to generate methods. That is, the inline method.

Reference from C # head Architect Anders Hejlsberg:

Www.ondotnet.com/..page%2

Lambda expressions and anonymous methods are really just two words for the same thing. The only thing that differs is, "What does the syntax look like? "And the lambda expressions are a further evolution of the syntax. But underneath, they do the same thing. They generate methods. You know, they're in-line methods.

Therefore, we should understand both the anonymous method and Lambda expression. Next, let's take a look at a simple code example, using anonymous methods and Lambda expressions to search for Arrays:

Use the. net 2.0 anonymous method to search for the string array containing

Static void Main (string [] args)
{
String [] list = new string [] {"abc", "12", "java "};
String [] ll = Array. FindAll (list,
Delegate (string s)
{
Return s. IndexOf ("a")> = 0;
}
);
Foreach (string var in ll)
{
Console. WriteLine (var );
}
Console. ReadLine ();
}

Use a. net 3.5 Lambda expression to search for a string array containing

Static void Main (string [] args)
{
String [] list = new string [] {"abc", "12", "java "};

String [] ll = Array. FindAll (list, s => (s. IndexOf ("a")> = 0 ));
Foreach (string var in ll) ...... remaining full text>

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.