What is the difference between lambdas and delegat

2019-01-29 18:12发布

I get asked this question a lot and I thought I'd solicit some input on how to best describe the difference.

标签: c# .net lambda
17条回答
劫难
2楼-- · 2019-01-29 18:55

Delegates are equivalent to function pointers/method pointers/callbacks (take your pick), and lambdas are pretty much simplified anonymous functions. At least that's what I tell people.

查看更多
欢心
3楼-- · 2019-01-29 18:55

Well, the really oversimplified version is that a lambda is just shorthand for an anonymous function. A delegate can do a lot more than just anonymous functions: things like events, asynchronous calls, and multiple method chains.

查看更多
劳资没心,怎么记你
4楼-- · 2019-01-29 18:56

I don't have a ton of experience with this, but the way I would describe it is that a delegate is a wrapper around any function, whereas a lambda expression is itself an anonymous function.

查看更多
The star\"
5楼-- · 2019-01-29 18:56

A delegate is a Queue of function pointers, invoking a delegate may invoke multiple methods. A lambda is essentially an anonymous method declaration which may be interpreted by the compiler differently, depending on what context it is used as.

You can get a delegate that points to the lambda expression as a method by casting it into a delegate, or if passing it in as a parameter to a method that expects a specific delegate type the compiler will cast it for you. Using it inside of a LINQ statement, the lambda will be translated by the compiler into an expression tree instead of simply a delegate.

The difference really is that a lambda is a terse way to define a method inside of another expression, while a delegate is an actual object type.

查看更多
劳资没心,怎么记你
6楼-- · 2019-01-29 19:03

Heres an example I put up awhile on my lame blog. Say you wanted to update a label from a worker thread. I've got 4 examples of how to update that label from 1 to 50 using delegates, anon delegates and 2 types of lambdas.

 private void button2_Click(object sender, EventArgs e) 
     { 
         BackgroundWorker worker = new BackgroundWorker(); 
         worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
         worker.RunWorkerAsync(); 
     } 

     private delegate void UpdateProgDelegate(int count); 
     private void UpdateText(int count) 
     { 
         if (this.lblTest.InvokeRequired) 
         { 
             UpdateProgDelegate updateCallBack = new UpdateProgDelegate(UpdateText); 
             this.Invoke(updateCallBack, new object[] { count }); 
         } 
         else 
         { 
             lblTest.Text = count.ToString(); 
         } 
     } 

     void worker_DoWork(object sender, DoWorkEventArgs e) 
     {   
         /* Old Skool delegate usage.  See above for delegate and method definitions */ 
         for (int i = 0; i < 50; i++) 
         { 
             UpdateText(i); 
             Thread.Sleep(50); 
         } 

         // Anonymous Method 
         for (int i = 0; i < 50; i++) 
         { 
             lblTest.Invoke((MethodInvoker)(delegate() 
             { 
                 lblTest.Text = i.ToString(); 
             })); 
             Thread.Sleep(50); 
         } 

         /* Lambda using the new Func delegate. This lets us take in an int and 
          * return a string.  The last parameter is the return type. so 
          * So Func<int, string, double> would take in an int and a string 
          * and return a double.  count is our int parameter.*/ 
         Func<int, string> UpdateProgress = (count) => lblTest.Text = count.ToString(); 
         for (int i = 0; i < 50; i++) 
         { 
             lblTest.Invoke(UpdateProgress, i); 
             Thread.Sleep(50); 
         } 

         /* Finally we have a totally inline Lambda using the Action delegate 
          * Action is more or less the same as Func but it returns void. We could 
          * use it with parameters if we wanted to like this: 
          * Action<string> UpdateProgress = (count) => lblT…*/ 
         for (int i = 0; i < 50; i++) 
         { 
             lblTest.Invoke((Action)(() => lblTest.Text = i.ToString())); 
             Thread.Sleep(50); 
         } 
     }
查看更多
登录 后发表回答