jeudi 17 avril 2014

c# 3.0 - expression c# Lambda, pourquoi devrais-je utiliser cela ? -Débordement de pile


I have quickly read the Microsoft Lambda Expression documentation.


I see example that have help me to understand more like this one :


delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

But, I still do not understand why it's so an innovation. It's just a method that die when the "method variable" end, right? Why should I use this instead of real method?




Lambda expressions are a simpler syntax for anonymous delegates and can be used everywhere an anonymous delegate can be used. However, the opposite is not true; lambda expressions can be converted to expression trees which allows for a lot of the magic like LINQ to SQL.


The following is an example of a LINQ to Objects expression using anonymous delegates then lambda expressions to show how much easier on the eye they are:


// anonymous delegate
var evens = Enumerable
.Range(1, 100)
.Where(delegate(int x) { return (x % 2) == 0; })
.ToList();

// lambda expression
var evens = Enumerable
.Range(1, 100)
.Where(x => (x % 2) == 0)
.ToList();

Lambda expressions and anonymous delegates have an advantage over writing a separate function: they implement closures which can allow you to pass local state to the function without adding parameters to the function or creating one-time-use objects.


Expression trees are a very powerful new feature of C# 3.0 that allow an API to look at the structure of an expression instead of just getting a reference to a method that can be executed. An API just has to make a delegate parameter into an Expression<T> parameter and the compiler will generate an expression tree from a lambda instead of an anonymous delegate:


void Example(Predicate<int> aDelegate);

called like:


Example(x => x > 5);

becomes:


void Example(Expression<Predicate<int>> expressionTree);

The latter will get passed a representation of the abstract syntax tree that describes the expression x > 5. LINQ to SQL relies on this behavior to be able to turn C# expressions in to the SQL expressions desired for filtering / ordering / etc. on the server side.




Anonymous functions and expressions are useful for one-off methods that don't benifit from the extra work required to create a full method.


Consider this example:


 string person = people.Find(person => person.Contains("Joe"));

versus


 public string FindPerson(string nameContains, List<string> persons)
{
foreach (string person in persons)
if (person.Contains(nameContains))
return person;
return null;
}

These are functionally equalivalant.




I found them useful in a situation when I wanted to declare a handler for some control's event, using another control. To do it normally you would have to store controls' references in fields of the class so that you could use them in a different method than they were created.


private ComboBox combo;
private Label label;

public CreateControls()
{
combo = new ComboBox();
label = new Label();
//some initializing code
combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);
}

void combo_SelectedIndexChanged(object sender, EventArgs e)
{
label.Text = combo.SelectedValue;
}

thanks to lambda expressions you can use it like this:


public CreateControls()
{
ComboBox combo = new ComboBox();
Label label = new Label();
//some initializing code
combo.SelectedIndexChanged += (sender, eventArgs) => {label.Text = combo.SelectedValue;};
}

Much easier.




Lambda's cleaned up C# 2.0's anonymous delegate syntax...for example


Strings.Find(s => s == "hello");

Was done in C# 2.0 like this:


Strings.Find(delegate(String s) { return s == "hello"; });

Functionally, they do the exact same thing, its just a much more concise syntax.




This is just one way of using a lambda expression. You can use a lambda expression anywhere you can use a delegate. This allows you to do things like this:


List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

strings.Find(s => s == "hello");

This code will search the list for an entry that matches the word "hello". The other way to do this is to actually pass a delegate to the Find method, like this:


List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

private static bool FindHello(String s)
{
return s == "hello";
}

strings.Find(FindHello);

EDIT:


In C# 2.0, this could be done using the anonymous delegate syntax:


  strings.Find(delegate(String s) { return s == "hello"; });

Lambda's significantly cleaned up that syntax.




Microsoft has given us a cleaner, more convenient way of creating anonymous delegates called Lambda expressions. However, there is not a lot of attention being paid to the expressions portion of this statement. Microsoft released a entire namespace, System.Linq.Expressions, which contains classes to create expression trees based on lambda expressions. Expression trees are made up of objects that represent logic. For example, x = y + z is an expression that might be part of an expression tree in .Net. Consider the following (simple) example:


using System;
using System.Linq;
using System.Linq.Expressions;


namespace ExpressionTreeThingy
{
class Program
{
static void Main(string[] args)
{
Expression<Func<int, int>> expr = (x) => x + 1; //this is not a delegate, but an object
var del = expr.Compile(); //compiles the object to a CLR delegate, at runtime
Console.WriteLine(del(5)); //we are just invoking a delegate at this point
Console.ReadKey();
}
}
}

This example is trivial. And I am sure you are thinking, "This is useless as I could have directly created the delegate instead of creating an expression and compiling it at runtime". And you would be right. But this provides the foundation for expression trees. There are a number of expressions available in the Expressions namespaces, and you can build your own. I think you can see that this might be useful when you don't know exactly what the algorithm should be at design or compile time. I saw an example somewhere for using this to write a scientific calculator. You could also use it for Bayesian systems, or for genetic programming (AI). A few times in my career I have had to write Excel-like functionality that allowed users to enter simple expressions (addition, subtrations, etc) to operate on available data. In pre-.Net 3.5 I have had to resort to some scripting language external to C#, or had to use the code-emitting functionality in reflection to create .Net code on the fly. Now I would use expression trees.




It saves having to have methods that are only used once in a specific place from being defined far away from the place they are used. Good uses are as comparators for generic algorithms such as sorting, where you can then define a custom sort function where you are invoking the sort rather than further away forcing you to look elsewhere to see what you are sorting on.


And it's not really an innovation. LISP has had lambda functions for about 30 years or more.




A lot of the times, you are only using the functionality in one place, so making a method just clutters up the class.




It's a way of taking small operation and putting it very close to where it is used (not unlike declaring a variable close to its use point). This is supposed to make your code more readable. By anonymizing the expression, you're also making it a lot harder for someone to break your client code if it the function is used somewhere else and modified to "enhance" it.


Similarly, why do you need to use foreach? You can do everything in foreach with a plain for loop or just using IEnumerable directly. Answer: you don't need it but it makes your code more readable.




Lambda expression is a concise way to represent an anonymous method. Both anonymous methods and Lambda expressions allow you define the method implementation inline, however, an anonymous method explicitly requires you to define the parameter types and the return type for a method. Lambda expression uses the type inference feature of C# 3.0 which allows the compiler to infer the type of the variable based on the context. It’s is very convenient because that saves us a lot of typing!




A lambda expression is like an anonymous method written in place of a delegate instance.


delegate int MyDelagate (int i);
MyDelagate delSquareFunction = x => x * x;

Consider the lambda expression x => x * x;



The input parameter value is x (on the left side of =>)


The function logic is x * x (on the right side of =>)



A lambda expression's code can be a statement block instead of an expression.


x => {return x * x;};

Example


Note: Func is a predefined generic delegate.


    Console.WriteLine(MyMethod(x => "Hi " + x));

public static string MyMethod(Func<string, string> strategy)
{
return strategy("Lijo").ToString();
}

References



  1. C# how can a delegate & interface method interchangable




You can also find the use of lambda expressions in writing generic codes to act on your methods.


For example: Generic function to calculate the time taken by a method call. (i.e. Action in here)


public static long Measure(Action action)
{
Stopwatch sw = new Stopwatch();
sw.Start();
action();
sw.Stop();
return sw.ElapsedMilliseconds;
}

And you can call the above method using the lambda expression as follows,


var timeTaken = Measure(() => yourMethod(param));

Expression allows you to get return value from your method and out param as well


var timeTaken = Measure(() => returnValue = yourMethod(param, out outParam));


I have quickly read the Microsoft Lambda Expression documentation.


I see example that have help me to understand more like this one :


delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

But, I still do not understand why it's so an innovation. It's just a method that die when the "method variable" end, right? Why should I use this instead of real method?



Lambda expressions are a simpler syntax for anonymous delegates and can be used everywhere an anonymous delegate can be used. However, the opposite is not true; lambda expressions can be converted to expression trees which allows for a lot of the magic like LINQ to SQL.


The following is an example of a LINQ to Objects expression using anonymous delegates then lambda expressions to show how much easier on the eye they are:


// anonymous delegate
var evens = Enumerable
.Range(1, 100)
.Where(delegate(int x) { return (x % 2) == 0; })
.ToList();

// lambda expression
var evens = Enumerable
.Range(1, 100)
.Where(x => (x % 2) == 0)
.ToList();

Lambda expressions and anonymous delegates have an advantage over writing a separate function: they implement closures which can allow you to pass local state to the function without adding parameters to the function or creating one-time-use objects.


Expression trees are a very powerful new feature of C# 3.0 that allow an API to look at the structure of an expression instead of just getting a reference to a method that can be executed. An API just has to make a delegate parameter into an Expression<T> parameter and the compiler will generate an expression tree from a lambda instead of an anonymous delegate:


void Example(Predicate<int> aDelegate);

called like:


Example(x => x > 5);

becomes:


void Example(Expression<Predicate<int>> expressionTree);

The latter will get passed a representation of the abstract syntax tree that describes the expression x > 5. LINQ to SQL relies on this behavior to be able to turn C# expressions in to the SQL expressions desired for filtering / ordering / etc. on the server side.



Anonymous functions and expressions are useful for one-off methods that don't benifit from the extra work required to create a full method.


Consider this example:


 string person = people.Find(person => person.Contains("Joe"));

versus


 public string FindPerson(string nameContains, List<string> persons)
{
foreach (string person in persons)
if (person.Contains(nameContains))
return person;
return null;
}

These are functionally equalivalant.



I found them useful in a situation when I wanted to declare a handler for some control's event, using another control. To do it normally you would have to store controls' references in fields of the class so that you could use them in a different method than they were created.


private ComboBox combo;
private Label label;

public CreateControls()
{
combo = new ComboBox();
label = new Label();
//some initializing code
combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);
}

void combo_SelectedIndexChanged(object sender, EventArgs e)
{
label.Text = combo.SelectedValue;
}

thanks to lambda expressions you can use it like this:


public CreateControls()
{
ComboBox combo = new ComboBox();
Label label = new Label();
//some initializing code
combo.SelectedIndexChanged += (sender, eventArgs) => {label.Text = combo.SelectedValue;};
}

Much easier.



Lambda's cleaned up C# 2.0's anonymous delegate syntax...for example


Strings.Find(s => s == "hello");

Was done in C# 2.0 like this:


Strings.Find(delegate(String s) { return s == "hello"; });

Functionally, they do the exact same thing, its just a much more concise syntax.



This is just one way of using a lambda expression. You can use a lambda expression anywhere you can use a delegate. This allows you to do things like this:


List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

strings.Find(s => s == "hello");

This code will search the list for an entry that matches the word "hello". The other way to do this is to actually pass a delegate to the Find method, like this:


List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

private static bool FindHello(String s)
{
return s == "hello";
}

strings.Find(FindHello);

EDIT:


In C# 2.0, this could be done using the anonymous delegate syntax:


  strings.Find(delegate(String s) { return s == "hello"; });

Lambda's significantly cleaned up that syntax.



Microsoft has given us a cleaner, more convenient way of creating anonymous delegates called Lambda expressions. However, there is not a lot of attention being paid to the expressions portion of this statement. Microsoft released a entire namespace, System.Linq.Expressions, which contains classes to create expression trees based on lambda expressions. Expression trees are made up of objects that represent logic. For example, x = y + z is an expression that might be part of an expression tree in .Net. Consider the following (simple) example:


using System;
using System.Linq;
using System.Linq.Expressions;


namespace ExpressionTreeThingy
{
class Program
{
static void Main(string[] args)
{
Expression<Func<int, int>> expr = (x) => x + 1; //this is not a delegate, but an object
var del = expr.Compile(); //compiles the object to a CLR delegate, at runtime
Console.WriteLine(del(5)); //we are just invoking a delegate at this point
Console.ReadKey();
}
}
}

This example is trivial. And I am sure you are thinking, "This is useless as I could have directly created the delegate instead of creating an expression and compiling it at runtime". And you would be right. But this provides the foundation for expression trees. There are a number of expressions available in the Expressions namespaces, and you can build your own. I think you can see that this might be useful when you don't know exactly what the algorithm should be at design or compile time. I saw an example somewhere for using this to write a scientific calculator. You could also use it for Bayesian systems, or for genetic programming (AI). A few times in my career I have had to write Excel-like functionality that allowed users to enter simple expressions (addition, subtrations, etc) to operate on available data. In pre-.Net 3.5 I have had to resort to some scripting language external to C#, or had to use the code-emitting functionality in reflection to create .Net code on the fly. Now I would use expression trees.



It saves having to have methods that are only used once in a specific place from being defined far away from the place they are used. Good uses are as comparators for generic algorithms such as sorting, where you can then define a custom sort function where you are invoking the sort rather than further away forcing you to look elsewhere to see what you are sorting on.


And it's not really an innovation. LISP has had lambda functions for about 30 years or more.



A lot of the times, you are only using the functionality in one place, so making a method just clutters up the class.



It's a way of taking small operation and putting it very close to where it is used (not unlike declaring a variable close to its use point). This is supposed to make your code more readable. By anonymizing the expression, you're also making it a lot harder for someone to break your client code if it the function is used somewhere else and modified to "enhance" it.


Similarly, why do you need to use foreach? You can do everything in foreach with a plain for loop or just using IEnumerable directly. Answer: you don't need it but it makes your code more readable.



Lambda expression is a concise way to represent an anonymous method. Both anonymous methods and Lambda expressions allow you define the method implementation inline, however, an anonymous method explicitly requires you to define the parameter types and the return type for a method. Lambda expression uses the type inference feature of C# 3.0 which allows the compiler to infer the type of the variable based on the context. It’s is very convenient because that saves us a lot of typing!



A lambda expression is like an anonymous method written in place of a delegate instance.


delegate int MyDelagate (int i);
MyDelagate delSquareFunction = x => x * x;

Consider the lambda expression x => x * x;



The input parameter value is x (on the left side of =>)


The function logic is x * x (on the right side of =>)



A lambda expression's code can be a statement block instead of an expression.


x => {return x * x;};

Example


Note: Func is a predefined generic delegate.


    Console.WriteLine(MyMethod(x => "Hi " + x));

public static string MyMethod(Func<string, string> strategy)
{
return strategy("Lijo").ToString();
}

References



  1. C# how can a delegate & interface method interchangable



You can also find the use of lambda expressions in writing generic codes to act on your methods.


For example: Generic function to calculate the time taken by a method call. (i.e. Action in here)


public static long Measure(Action action)
{
Stopwatch sw = new Stopwatch();
sw.Start();
action();
sw.Stop();
return sw.ElapsedMilliseconds;
}

And you can call the above method using the lambda expression as follows,


var timeTaken = Measure(() => yourMethod(param));

Expression allows you to get return value from your method and out param as well


var timeTaken = Measure(() => returnValue = yourMethod(param, out outParam));

0 commentaires:

Enregistrer un commentaire