C#2.0 introduces a new feature-anonymous method that allows developers to declare their own function code online (inline) without using a delegate function (delegate function). C#3.0 provides a new feature--LAMBDA expression that provides a more concise format for accomplishing the same goal. Let's take a closer look at anonymous methods before discussing lambda expressions.
anonymous Method
Suppose you need to create a button that updates the contents of the ListBox when you click it. In c#1.0 and 1.1, you have to do this:
Public MyForm ()
{
ListBox = new ListBox (...);
TextBox = new TextBox (...);
AddButton = new Button (...);
Addbutton.click + = new EventHandler (AddClick);
}
void AddClick (object sender, EventArgs e)
{
LISTBOX.ITEMS.ADD (TextBox.Text);
}
In c#2.0, you need to do this:
Public MyForm ()
{
ListBox = new ListBox (...);
TextBox = new TextBox (...);
AddButton = new Button (...);
Addbutton.click + + Delegate
{
LISTBOX.ITEMS.ADD (TextBox.Text);
};
As you can see, you don't have to specifically declare a new method to connect it to an event. You can use anonymous methods in c#2.0 to do the same job. C#3.0 introduces a simpler format, lambda expression, you can use "=>" to write your expression list, followed by an expression or statement block.
parameters in a lambda expression
Parameters in a lambda expression can be explicit or implicitly typed. In an explicit type parameter list, the type of each expression is explicitly specified. In an implicit type parameter list, the type is inferred from the context:
(int x) => x + 1//Explicit type parameters
(y,z) => return y * z; Implicit type parameters
Lambda calculus instance
The following example shows two different ways to print a string with an even length in a list. The first method Anonmethod uses the anonymous method, and the second lambdaexample is implemented through the lambda calculus:
Program.cs
Using System;
Using System.Collections.Generic;
Using System.Text;
Using System.query;
Using System.Xml.XLinq;
Using System.Data.DLinq;
Namespace Lambdaexample
{
Public delegate bool Keyvaluefilter<k, v> (K key, V value);
Static Class Program
{
static void Main (string[] args)
{
list<string> list = new list<string> ();
List. ADD ("AA");
List. ADD ("ABC");
List. ADD ("DEFG");
List. ADD ("XYZ");
Console.WriteLine ("Through Anonymous method");
Anonmethod (list);
Console.WriteLine ("Through LAMBDA expression");
Lambdaexample (list);
Dictionary<string, int> varclothes= new dictionary<string,int> ();
Varclothes.add ("Jeans", 20);
Varclothes.add ("shirts", 15);
Varclothes.add ("Pajamas", 9);
Varclothes.add ("Shoes", 9);
var clotheslistshortage = Varclothes.filterby (string name,
int count) => name = = "Shoes" && count < 10);
Example of multiple parameters
if (Clotheslistshortage.count > 0)
Console.WriteLine ("We are short of shoes");
Console.ReadLine ();
}
static void Anonmethod (List<string> List)
{
list<string> evennumbers = list. FindAll (Delegate (String i)
{return (i.length% 2) = = 0;});
foreach (String evennumber in Evennumbers)
{
Console.WriteLine (Evennumber);
}
}
static void Lambdaexample (List<string> List)
{
var evennumbers = list. FindAll (i => (i.length% 2) = = 0); Example of single parameter
foreach (String i in Evennumbers)
{
Console.WriteLine (i);
}
}
}
public static Class Extensions
{
public static dictionary<k, v> filterby<k, v>
(This dictionary<k, v> items, keyvaluefilter<k, v> filter)
{
var result = new dictionary<k, v> ();
foreach (keyvaluepair<k, v> element in items)
{
If filter (element. Key, Element. Value))
Result. ADD (element. Key, Element. Value);
}
return result;
}
}
}
If you have a visual Studio and LinQ Preview installed, you can use the editor to compile the program. If not, you can use the command-line method:
C:\Program files\linq Preview\bin\csc.exe
/reference: "C:\Program files\linq Preview\bin\system.data.dlinq.dll"
/reference:c:\windows\microsoft.net\framework\v2.0.50727\system.data.dll
/reference:c:\windows\microsoft.net\framework\v2.0.50727\system.dll
/reference: "C:\Program files\linq Preview\bin\system.query.dll"
/reference:c:\windows\microsoft.net\framework\v2.0.50727\system.xml.dll
/reference: "C:\Program files\linq Preview\bin\system.xml.xlinq.dll"
/target:exe Program.cs
Intermediate Language results show
Double-click the Anonmethod function to see the intermediate language code generated by the C # compiler:
. method private Hidebysig static void Anonmethod (class
[mscorlib] System.Collections.Generic.List ' 1<string> List)
CIL managed
{
Code size (0x60)
. maxstack 4
. Locals init ([0] class [mscorlib]system.collections.generic.list
' 1<string> evennumbers,
[1] string evennumber,
[2] valuetype [mscorlib]system.collections.generic.list
' 1/enumerator<string> Cscode_replacement 000,
[3] bool Cscode_replacement 001)
Il_0000:nop
il_0001:ldarg.0
IL_0002:LDSFLD class [Mscorlib]system.predicate
' 1<string> Lambdaexample.program::
' <>9__cachedanonymousmethoddelegate1 '
IL_0007:BRTRUE.S il_001c
Il_0009:ldnull
il_000a:ldftn bool Lambdaexample.program::
' <anonmethod>b__0 ' (string)
Il_0010:newobj instance void class [Mscorlib]system.predicate
' 1<string>::.ctor (object, native int)
IL_0015:STSFLD class [Mscorlib]system.predicate ' 1<string>
Lambdaexample.program::
' <>9__cachedanonymousmethoddelegate1 '
IL_001A:BR.S il_001c
IL_001C:LDSFLD class [Mscorlib]system.predicate ' 1<string>
Lambdaexample.program:: ' <>
9__cachedanonymousmethoddelegate1 '
Il_0021:callvirt instance class [Mscorlib]system.collections.
Generic.list ' 1<!0> class [Mscorlib]system.
Collections.Generic.List ' 1<string>::
FindAll (class [Mscorlib]system.predicate ' 1<!0>)
il_0026:stloc.0
Il_0027:nop
il_0028:ldloc.0
Il_0029:callvirt instance valuetype [Mscorlib]system.collections.
Generic.list ' 1/enumerator<!0> class
[mscorlib] System.Collections.Generic.List ' 1
<string>::getenumerator ()
Il_002e:stloc.2
. try
{
IL_002F:BR.S il_0042
IL_0031:LDLOCA.S Cscode_replacement 000
Il_0033:call instance!0 valuetype [Mscorlib]system.
Collections.Generic.List ' 1/enumerator
<string>::get_current ()
Il_0038:stloc.1
Il_0039:nop
Il_003a:ldloc.1
Il_003b:call void [mscorlib]System.Console::
WriteLine (String)
Il_0040:nop
Il_0041:nop
IL_0042:LDLOCA.S Cscode_replacement 000
Il_0044:call instance bool ValueType [Mscorlib]system.
Collections.Generic.List ' 1/enumerator
<string>::movenext ()
Il_0049:stloc.3
Il_004a:ldloc.3
IL_004B:BRTRUE.S il_0031
IL_004D:LEAVE.S il_005e
}//end. Try
Finally
{
IL_004F:LDLOCA.S Cscode_replacement 000
il_0051:constrained. ValueType [Mscorlib]system.collections.
Generic.list ' 1/enumerator<string>
Il_0057:callvirt instance void [Mscorlib]system.
IDisposable::D ispose ()
Il_005c:nop
Il_005d:endfinally
}//End Handler
Il_005e:nop
Il_005f:ret
}//End of method Program::anonmethod
Here we can see that in fact anonymous methods and lambda expressions generate the same intermediate code, and their execution is similar.
Multi-parameter lambda expression
Lambda expressions can take multiple arguments, such as you can declare a dictionary type:
Clothing Type |
Count |
Shirts |
15 |
Jeans |
12 |
Shoes |
9 |
Pajamas |
9 |
If you have an anonymous method (Filterby) to filter the dictionary by key and value, click on it you can pass multiple arguments to the lambda expression to invoke the anonymous method. The accompanying code completes this Filterby function:
var clotheslistshortage = Clotheslist.filterby ((string name, int count)
=> name = = "Shoes" && count < 10);