1. What does happen when we pass a peace of code as a parameter to a method?
2. What does tree expression mean?
3. What are limitations of lambda expressions?
4. Do lambda expressions have access to external variables?
5. What are the types of lambda expressions?
6. What is a predicate?
7. What is a projection?
8. What is the difference between statements and expressions?
9. What is the difference between an expression tree and a delegate?
When we pass a peace of code as a parameter to a method we actually pass a reference to another method.
Code generation of lambda expressions can be postponed and be compiled at runtime, so code generation can be manipulated by programmer. In this case the code generation is called expression tree.
Example 1:
public class AggregationClass
{
public delegate T Func<T>(T a, T b);
public T Aggregate<T>(IEnumerable<T> data, Func<T> f)
{
T aggregateValue = default(T);
bool isFirst = true;
foreach (var el in data)
{
if (isFirst)
{
aggregateValue = el;
isFirst = false;
}
else
{
aggregateValue = f(aggregateValue, el);
}
}
return aggregateValue;
}
}
class Program
{
static void Main(string[] args)
{
AggregationClass aggregationClass = new AggregationClass();
Trace.WriteLine(aggregationClass.Aggregate(new []{"a", "b", "c"}, (a, b) => a + b));
Console.ReadKey();
}
}
Output:
abc
Given lambda expressions’ parameters must be support by generics constraint of their delegates. For example in the previous sample we can pass parameters which support the “+” operator only.
We can rewrite the Aggregate method using a new feature of the C# 3.0, extension methods.
Example 2:
public static class AggregationClass
{
public delegate T Func<T>(T a, T b);
public static T Aggregate<T>(this IEnumerable<T> data, Func<T> f)
{
T aggregateValue = default(T);
bool isFirst = true;
foreach (var el in data)
{
if (isFirst)
{
aggregateValue = el;
isFirst = false;
}
else
{
aggregateValue = f(aggregateValue, el);
}
}
return aggregateValue;
}
}
class Program
{
static void Main(string[] args)
{
string[] array = new[] { "a", "b", "c" };
string addSeparatorText = "|";
Trace.WriteLine(array.Aggregate((a, b) => a + addSeparatorText + b));
Console.ReadKey();
}
}
Output:
a|b|c
As we can see from the example above lambda expressions have access to a variables outside the expressions.