Lambda Expression as Predicate and Expression Tree in C# 3.0
Lambda Expression as Predicate and Expression Tree in C# 3.0
By : Kasim Wirama, MCSD.NET, MVP SQL Server
One of C# 3.0 new feature is lambda expression. What is it actually Lambda expression? How to use Lambda expression?
In C# 2.0, ability to pass method implementation to a delegate type is called anonymous method. In C# 3.0 with lambda expression, you can make definition of anonymous method is more concise.
Syntax of lambda expression has sign/operator => (combination of equal and greater than sign)
Typical use of simple delegate is provided in example below:
public delegate void MethodDlgt(string a, string b);
class Class1
{
public static void Main()
{
MethodDlgt dlgt = Method1;
dlgt("hello", "world");
Console.ReadLine();
}
public static void Method1(string a, string b)
{
Console.WriteLine("{0} {1}", a, b);
}
}
It will output "Hello World" message to console application when the sample above is run.
With lambda expression this sample above could be written as follows :
public delegate void MethodDlgt(string a, string b);
class Class1
{
public static void Main()
{
MethodDlgt dlgt = (a, b) => { Console.WriteLine("{0} {1}", a, b); };
dlgt("hello", "world");
Console.ReadLine();
}
}
As you can compare, the static method Method1 is directly assigned to delegate variable dlgt.
Delegate type before class declaration could be replace with built-in delegate type called Func, with has last parameter as return value with generic type, so the above example could be in more concise form as below :
class Class1
{
public static void Main()
{
Func<string, string,bool> dlgt = (a, b) => { Console.WriteLine("{0} {1}", a, b); return true; };
dlgt("hello", "world");
Console.ReadLine();
}
}
Another example, that make clear use of lambda expression, is to pass method execution through input parameter.
class Class1
{
public static void Main1()
{
string[] names = { "ali", "marco", "stephan" };
Display<string>(names, 4); Console.WriteLine();
Display<string>(names, "ali");
Console.ReadLine();
}
public static void Display<T>(T[] param1, string value)
{
foreach(T member in param1)
{
if (string.Equals(member , value))
{
Console.WriteLine(member);
}
}
}
public static void Display<T>(T[] param1, int length)
{
foreach (T member in param1)
{
if (member.ToString().Length >= length)
{
Console.WriteLine(member);
}
}
}
}
There are 2 overloading method, first method is to display searched value, second one is to display collection members that satisfy string length criteria. With lambda expression I could move if (member.ToString().Length >= length) { Console.WriteLine(member); } and if (string.Equals(member , value)) { Console.WriteLine(member); } into Main method, and reduce overloading method Display from 2 become 1, here is the code :
class Class1
{
public static void Main()
{
string[] names = { "ali", "marco", "stephan" };
Display(names, "ali", (member, b) => {if (member == b) { Console.WriteLine(member); }
return true;
}
);
Console.WriteLine();
Display(names, 3, (member, b) => { if (member.Length > b) {Console.WriteLine(member); }
return true; }
);
Console.ReadLine();
}
public static void Display<T,U,B>(T[] param1, U param2, Func<T,U,B> s)
{
foreach (T member in param1)
{
s(member, param2);
}
}
}
It is a bit confusing at first time, the way you understand the order of execution is to debug through visual studio and you will get the point.
Usually delegate is assigned to lambda expression. On this example, lambda expression is used as predicate. What is predicate?
Predicate is a Boolean expression, for example :
(a) => a > 5
Other terms is projection. Projection is a lambda expression that returns different type from input type
For example :
(a) => a.Length
a as string in input parameter, and return integer value from a.Length.
You should remember that lambda expression is not tied to built-in delegate (Func), it can be used with your own specified delegate.
Besides that, lambda expression can be used with Expression class. Expression class resides under System.Linq.Expressions. Here is the example :
class Class1
{
private delegate T Func<T>(T a, T b);
public static void Main1()
{
Expression<Func<int>> y = (a , b) => a + b;
Console.WriteLine(y.Compile()(5, 7));
Console.ReadLine();
}
}
There is method Compile on expression instance. Compile here returns a delegate that invoked by Invoke method. Expression tree is used in generating SQL statement by LINQ’s method by navigating the expression tree.
From these examples above, I can conclude that predicate with lambda expression is make your code shorter, and make your function is more flexible with greater coverage range of functionality through lambda expression.
It is our learning curve to grab lambda expression into daily .NET 3.5 codes.