.NET, Architecture, ALM, Cloud
C# Code :
Func<int, List<int>> foreachSample = (a) =>
{
List<int> myList = new List<int>();
IEnumerable<int> numbers = new int[] { 1, 2, 3, 4 };
foreach (int number in numbers)
myList.Add(number * 2);
return myList;
};
Expression Trees Code :
var aParam = Expression.Parameter(typeof(int), "a");
var myListVariable = Expression.Variable(typeof(List<int>), "myList");
var numbersVariable = Expression.Variable(typeof(IEnumerable<int>), "numbers");
var enumerator = Expression.Variable(typeof(IEnumerator<int>), "enumerator");
LabelTarget looplabel = Expression.Label("looplabel");
var assignenumerator =
Expression.Assign(enumerator, Expression.Call(numbersVariable, typeof(IEnumerable<int>).GetMethod("GetEnumerator")));
MethodCallExpression movenext = Expression.Call(enumerator, typeof(IEnumerator).GetMethod("MoveNext"));
var currentelement = Expression.Variable(typeof(int), "i");
var callCurrent = Expression.Assign(currentelement, Expression.Property(enumerator, "Current"));
Expression<Func<int, List<int>>> expression =
Expression.Lambda<Func<int, List<int>>>(
//{
Expression.Block(
new[] { myListVariable, numbersVariable, enumerator, currentelement },
//myList = new List<int>();
Expression.Assign(myListVariable, Expression.New(typeof(List<int>))),
//numbers = new int[] { 1, 2, 3, 4 };
Expression.Assign(numbersVariable, Expression.Constant(new int[] { 1, 2, 3, 4 })),
assignenumerator,
//foreach (int number in numbers)
Expression.Loop(
Expression.IfThenElse(movenext,
//myList.Add(number * 2);
Expression.Call(myListVariable, typeof(List<int>).GetMethod("Add"),
Expression.Multiply( callCurrent, aParam)),
Expression.Break(looplabel)), looplabel),
//return myList;
myListVariable),
aParam);
Expression Trees Debug View :
.Lambda #Lambda1<System.Func`2[System.Int32,System.Collections.Generic.List`1[System.Int32]]>(System.Int32 $a) {
.Block(
System.Collections.Generic.List`1[System.Int32] $myList,
System.Collections.Generic.IEnumerable`1[System.Int32] $numbers,
System.Collections.Generic.IEnumerator`1[System.Int32] $enumerator,
System.Int32 $i) {
$myList = .New System.Collections.Generic.List`1[System.Int32]();
$numbers = .Constant<System.Int32[]>(System.Int32[]);
$enumerator = .Call $numbers.GetEnumerator();
.Loop {
.If (
.Call $enumerator.MoveNext()
) {
.Call $myList.Add(($i = $enumerator.Current) * $a)
} .Else {
.Break looplabel { }
}
}
.LabelTarget looplabel:;
$myList
}
}
IL Code:
//myList = new List<int>();
IL_0000: newobj 08000000 is not a MethodDesc
6000003
//Get Enumerator
IL_0005: stloc.0
IL_0006: ldarg.0
IL_0007: ldfld 4000004 (02374db8)
IL_000c: ldc.i4.0
IL_000d: ldelem.ref
IL_000e: castclass 2000005 ""
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: callvirt 08000000 is not a MethodDesc
6000006
IL_001a: stloc.2
//foreach (int number in numbers)
IL_001b: ldloc.2
IL_001c: callvirt 6000007 System.Collections.IEnumerator.MoveNext()
IL_0021: brfalse IL_003b
//myList.Add(number * 2)
IL_0026: ldloc.0
IL_0027: ldloc.2
IL_0028: callvirt 08000000 is not a MethodDesc
6000008
IL_002d: dup
IL_002e: stloc.3
IL_002f: ldarg.1
IL_0030: mul
IL_0031: callvirt 08000000 is not a MethodDesc
6000009
IL_0036: br IL_0040
//break
IL_003b: br IL_0045
//Loop
IL_0040: br IL_001b
//return myList;
IL_0045: ldloc.0
IL_0046: ret