Calculating expression tree with many parameters - c#

I'm trying to use the Expression tree and Lamdba Expression objects in .Net 3.5 to allow me to dynamically calculate boolean expression entered by a user.
So far a user can create an expression tree consisting of BinarayExpressions that AND and OR values expressed as ParameterExpressions. I was then planning on creating a LambdaExpression based on that tree so that I could compile the expression into a delegate which I could then call. The issue I'm having is that I don't know how many input parameters the user will need so when I come to compile the expression into a delegate I don't know the method what the method signature should be until runtime.
So far I've come up with two possible solutions.
Create a whole bunch of delegates
like the Func<bool, bool, bool...> ones which can
take as many parameters as I think a user might possibly need. This doesn't feel like the most elegant solution but I think it would work, until someone wants to use one more parameter than I've catered for.
Pass in an array of values and somehow assign them to my parameters using the array indexer. I've thought about this but can't work out how it work.
NB: It needs to be quick so no boxing or anything like that.

I did exactly this before, using the array approach (for Finguistics, as it happens). The trick is Expression.ArrayIndex:
var arr = Expression.Parameter(typeof(int[]), "arr");
var body = Expression.ArrayIndex(arr, Expression.Constant(1));
var expr = Expression.Lambda<Func<int[], int>>(body, arr);
var func = expr.Compile();
int[] vals = { 7, 8, 9 };
int i = func(vals);
The advantage of the array approach is that you can keep a strongly typed delegate type (Func<int[],int> or similar, no matter the number of arguments. And typed Invoke is much faster than DynamicInvoke.
If the values aren't all of the same type - that is doable too; let me know and I'll add an example.

Related

How ToDictionary in c# works? [duplicate]

I have quickly read over the Microsoft Lambda Expression documentation.
This kind of example has helped me to understand better, though:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
Still, I don't understand why it's such an innovation. It's just a method that dies when the "method variable" ends, right? Why should I use this instead of a 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 benefit from the extra work required to create a full method.
Consider this example:
List<string> people = new List<string> { "name1", "name2", "joe", "another name", "etc" };
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 equivalent.
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 += (s, e) => {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.
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));
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
How can a delegate & interface be used interchangeably?
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.
The innovation is in the type safety and transparency. Although you don't declare types of lambda expressions, they are inferred, and can be used by code search, static analysis, refactoring tools, and runtime reflection.
For example, before you might have used SQL and could get an SQL injection attack, because a hacker passed a string where a number was normally expected. Now you would use a LINQ lambda expression, which is protected from that.
Building a LINQ API on pure delegates is not possible, because it requires combining expression trees together before evaluating them.
In 2016 most of the popular languages have lambda expression support, and C# was one of the pioneers in this evolution among the mainstream imperative languages.
The biggest benefit of lambda expressions and anonymous functions is the fact that they allow the client (programmer) of a library/framework to inject functionality by means of code in the given library/framework ( as it is the LINQ, ASP.NET Core and many others ) in a way that the regular methods cannot. However, their strength is not obvious for a single application programmer but to the one that creates libraries that will be later used by others who will want to configure the behaviour of the library code or the one that uses libraries. So the context of effectively using a lambda expression is the usage/creation of a library/framework.
Also since they describe one-time usage code they don't have to be members of a class where that will led to more code complexity. Imagine to have to declare a class with unclear focus every time we wanted to configure the operation of a class object.
Lambda expression makes tasks much simpler, for example
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var oddNumbers = numbers.Where(x => x % 2 != 0);
var sumOfEven = numbers.Where(x => x % 2 == 0).Sum();
In the above code, because we are using lambda, we are getting odd number and sum of even numbers in single line of code.
Without lambda, we will have to use if/else or for loop.
So it is good to use lambda to simplify code in C#.
Some articles on it:
https://qawithexperts.com/article/c-sharp/lambda-expression-in-c-with-examples/470
https://exceptionnotfound.net/csharp-in-simple-terms-18-expressions-lambdas-and-delegates
http://dontcodetired.com/blog/post/Whats-New-in-C-10-Easier-Lambda-Expressions
In C# we cannot pass functions as parameters like we do in JavaScript. The workaround is using delegates.
When we want to parameterize the behavior instead of a value, we use delegates. Lambdas are practical syntax for writing delegates which makes it very easy to pass around behavior as functions.
This is perhaps the best explanations on why to use lambda expressions -> https://youtu.be/j9nj5dTo54Q
In summary, it's to improve code readability, reduce chances of errors by reusing rather than replicating code, and leverage optimization happening behind the scenes.

Cache delegate of compiled Dynamic Linq Func<> *without* params?

I'm using the Dynamic.ParseLambda method from the Dynamic LINQ library to create expressions, compile each to a Func<>, and cache each in a dictionary:
// parse some dynamic expression using this ParseLambda sig:
Expression<Func<TArgument,TResult>> funcExpr =
System.Linq.Dynamic.ParseLambda<TArgument, TResult>(
expressionString, // string for dyn lambda expression
parameters); // object[] params
// then compile & cache the output of this as a delegate:
Func<TArgument,TResult> func = funcExpr.Compile(); //<-cache this
// then to execute, use:
return func(entityInstance);
The problem is, this forces me to cache a different delegate instance for every distinct set of parameter values. This seems kind of wasteful; all the overhead with Dynamic LINQ is in the parsing and compilation; once created, the delegates are near directly coded lambdas in performance. Is there any way to move the params outside of the expression, so I can pass different values to a common cached delegate in when I call it (instead of when I'm creating it)?
// e.g. with params...
return func(entityInstance,parameters);
// or if params are the issue, multiple signatures are ok:
return func(entityInstance, intValue, stringValue);
I don't see any parameter-free .ParseLambda or .Compile signatures in System.Linq.Dynamic, so my hopes aren't high. Anyone know of a quick way to achieve this?
Thanks!
There is a trick here, that I have used before; you do something like an Expression<Func<object[], object>>, and embed the fetch-by-index and casting inside the expression. Then you have as many parameters as you could want, a single signature, and reasonable performance. It does, however, make writing the lambda a bit tricker.
I don't have my old code for this "to hand", but if I needed to reverse engineer it, I would simply write something typical like the following, and then look in reflector to see what it used:
Expression<Func<object[], object>> func = arr => ((string)arr[0]) + (int)arr[1];
(in particular, paying attention to the indexer usage, the casting from inputs, and the casting to output)

Is it possible to cast a delegate instance into a Lambda expression?

Here the context for my question:
A common technique is to declare the parameter of a method as a Lambda expression rather than a delegate. This is so that the method can examine the expression to do interesting things like find out the names of method calls in the body of the delegate instance.
Problem is that you lose some of the intelli-sense features of Resharper. If the parameter of the method was declared as a delegate, Resharper would help out when writing the call to this method, prompting you with the x => x syntax to supply as the argument value to this method.
So... back to my question I would like to do the follow:
MethodThatTakesDelegate(s => s.Length);
}
private void MethodThatTakesDelegate(Func<string, object> func)
{
//convert func into expression
//Expression<Func<string, object>> expr = "code I need to write"
MethodThatTakesExpression(expr);
}
private void MethodThatTakesExpression(Expression<Func<string, object>> expr)
{
//code here to determine the name of the property called against string (ie the Length)
}
Everywhere that you're using the term "lambda expression" you actually mean "expression tree".
A lambda expression is the bit in source code which is
parameters => code
e.g.
x => x * 2
Expression trees are instances of the System.Linq.Expressions.Expression class (or rather, one of the derived classes) which represent code as data.
Lambda expressions are converted by the compiler into either expression trees (or rather, code which generates an expression tree at execution time) or delegate instances.
You can compile an instance of LambdaExpression (which is one of the subclasses of Expression) into a delegate, but you can't go the other way round.
In theory it might be possible to write such a "decompiler" based on the IL returned by MethodBase.GetMethodBody in some situations, but currently there are various delegates which can't be represented by expression trees. An expression tree represents an expression rather than a statement or statement block - so there's no looping, branching (except conditionals), assignment etc. I believe this may change in .NET 4.0, though I wouldn't expect a decompilation step from Microsoft unless there's a really good reason for one.
I don't believe it's possible to achieve what you'd like here. From the comments in your code it looks like you are attempting to capture the name of the property which did the assignment in MethodThatTakesExpression. This requires an expression tree lambda expression which captures the contexnt of the property access.
At the point you pass a delegate into MethodThatTakesDelegate this context is lost. Delegates only store a method address not any context about the method information. Once this conversion is made it's not possible to get it back.
An example of why this is not possible is that there might not even be a named method backing a delegate. It's possible to use ReflectionEmit to generate a method which has no name whatsoever and only exists in memory. It is possible though to assign this out to a Func object.
No, it is not possible.

Confused about LINQ parameters

I am trying to understand LINQ and become confident at using it. What I am struggling with are the parameters asked for. Example:
var sortedWords = words.OrderBy(a=>a.Length)
words is an array collection. OrderBy's intellisense says:
Func<string, TKey> keyselector
A func executes a method, and a string is the value, TKey a key.
In the example http://msdn.microsoft.com/en-us/vcsharp/aa336756.aspx#thenBySimple (ThenBy - Comparer), we compare length by saying a => a.Length. I understand that syntax, but how is that related to what the intellisense is asking for?
I tend to find the method signature and intellisense unreadable because of all the generics.
Thanks.
The type (as displayed by Intellisense) makes sense if you understand the nature of lambda expressions in .NET/C#. Otherwise, it can indeed seem a bit strange to the newcomer. Begin by considering that the type of keySelector, Func<TSource, TKey> is simply a delegate. Before C# 3.0, you would call such a method by passing a delegate as a parameter, for example:
IEnumerable<string> sortedWords = words.OrderBy(new Func<string, int>(mySelectorMethod));
where mySelectorMethod is the name of an ordinary method which takes a string as a parameter and returns an int. (As a side point, I suppose you could use anonymous delegates, but let's not go there for now.) Also, note that this example is purely illustrative, as LINQ is almost always used with .NET 3.5/C# 3.0 (though I believe it can be used with either/both .NET 2.0/C# 2.0 - someone correct me if I'm wrong). Since C# 3.0, methods can be defined inline as lambda expressions, which are intended to be used in precisely such circumstances as these. Read over the MSDN article on lambda expressions (linked above) if you want to get a proper introduction, but here I will simply describe the use in this specific context. As you state, your code (in C# 3.0) is something like the following:
var sortedWords = words.OrderBy(a => a.Length);
The part of the expression that is a => a.Length is the lambda expression, which is really just shorthand for declaring a function inline. The syntax of lambda expressions is quite simple for the most part; to the left of the => the arguments are specified, generally in the form (arg1, arg2, arg3), but since there's only one in this case you can omit the brackets. To the right of the => is the expression that is the return value of the function (lambda expression more accurately). Alternatively you can enclose actual code with a return statement within { and } though this is usually unnecessary. What I believe the C# compiler does is recognises the parameter passed to OrderBy as a lambda expression and then compiles it into a function and creates and passes the delegate for you. Note that lambda expressions can also be converted to System.Linq.Expressions.Expression objects (accessible expression trees) instead of delegates, but this is a much less common usage. Anyway, there's a lot going on behind the scenes here, but hopefully this should at least clarify why the type is Func<TSource, TKey> and how it relates to the lambda expression. As I said, read up on MSDN if you want a deeper understanding of LINQ/lambdas/delegates...
a => a.Length
I understand that syntax, but how is that related to what the intellisense is asking for?
This chunk of code is a lambda expression. A lambda expression is a handy way of generating an Anonymous method (in this case), or a System.Linq.Expressions.Expression . Let's break it down by parts.
The most noticeable feature is the =>, which seperates parameters from a method body.
On the left side of the =>, there is a symbol: a. This is the declaration of a parameter for our anonymous method. The compiler is aware that we are calling OrderBy(), and that OrderBy requires a Func<string, object>. The parameter for such a function is a string, so the compiler determines that a must be a string. The only thing the programmer needed to provide is a name.
On the right side of the =>, there is method body. Since this is a one-liner, the return keyword is implied. The IDE provides intellisense against a as a string, which allows you to use the Length property.
Now, consider this C# 2.0 ...
IEnumerable<string> sortedWords =
Enumerable.OrderBy(words, delegate(string a) {return a.Length;});
With the C# 3.0
IEnumerable<string> sortedWords = words
.OrderBy(a => a.Length);
I think the IntelliSense is actually quite useful, especially for generic methods that take Func<..> type as an argument, because you can see the types and types guide you to understand what the method might do.
For example, the arguments for OrderBy are IEnumerable<string> as a 'this' argument, which means that we have some input containing collection of strings. The first argument keySelector has a type Func<string, TKey>, which means that it is some lambda expression you provide that specifies how to get TKey from string.
This already suggests that the method will probably enumerate over all the items (strings) in the collection and it can use the keySelector to get value of type TKey from every element in the collection. The name TKey already suggests that it will use this value to compare the elements (strings) using this calculated key. However, if you look at the other overload that takes IComparer<TKey> then you can be sure about this - this argument specifies more details about how do you want to compare two values of type TKey, so the function must compare the elements using this key.
... this kind of thinking about types takes some time to get used to, but once you'll learn it, it can be extremely helpful. It is more useful in "functional" style of code, which often uses a lot of generics and lamdba expressions in C# 3.0 (and similar things in functional languages like F# or others)
I never really worry about the Intellisense, to be honest. It was messing me up early in my Linqage. As I spent more time with generics and expressions, it started to make sense, but up until then I just pumped in the syntax.
What it wants is a lambda expression that tells Linq what to look for in order to sort your collection.
I feel you, my brother, hang in there and it will make sense very soon.
OrderBy() takes a delegate for a function that accepts a single parameter (in your case, a string) and returns a value of the type that is substituted for TKey. It may be that the parameter type (string) was already determined since you called the method on an IEnumerable<string> but the delegate type will only be resolved as Func<string, int> after it infers it from the lambda expression when it is fully specified (i.e., a => a.Length). If you haven't given the parser any clues as to what you want as a sort key, it'll just show TKey in IntelliSense until it can determine the intended type.

C# Lambda expressions: Why should I use them?

I have quickly read over the Microsoft Lambda Expression documentation.
This kind of example has helped me to understand better, though:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
Still, I don't understand why it's such an innovation. It's just a method that dies when the "method variable" ends, right? Why should I use this instead of a 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 benefit from the extra work required to create a full method.
Consider this example:
List<string> people = new List<string> { "name1", "name2", "joe", "another name", "etc" };
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 equivalent.
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 += (s, e) => {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.
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));
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
How can a delegate & interface be used interchangeably?
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.
The innovation is in the type safety and transparency. Although you don't declare types of lambda expressions, they are inferred, and can be used by code search, static analysis, refactoring tools, and runtime reflection.
For example, before you might have used SQL and could get an SQL injection attack, because a hacker passed a string where a number was normally expected. Now you would use a LINQ lambda expression, which is protected from that.
Building a LINQ API on pure delegates is not possible, because it requires combining expression trees together before evaluating them.
In 2016 most of the popular languages have lambda expression support, and C# was one of the pioneers in this evolution among the mainstream imperative languages.
The biggest benefit of lambda expressions and anonymous functions is the fact that they allow the client (programmer) of a library/framework to inject functionality by means of code in the given library/framework ( as it is the LINQ, ASP.NET Core and many others ) in a way that the regular methods cannot. However, their strength is not obvious for a single application programmer but to the one that creates libraries that will be later used by others who will want to configure the behaviour of the library code or the one that uses libraries. So the context of effectively using a lambda expression is the usage/creation of a library/framework.
Also since they describe one-time usage code they don't have to be members of a class where that will led to more code complexity. Imagine to have to declare a class with unclear focus every time we wanted to configure the operation of a class object.
Lambda expression makes tasks much simpler, for example
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var oddNumbers = numbers.Where(x => x % 2 != 0);
var sumOfEven = numbers.Where(x => x % 2 == 0).Sum();
In the above code, because we are using lambda, we are getting odd number and sum of even numbers in single line of code.
Without lambda, we will have to use if/else or for loop.
So it is good to use lambda to simplify code in C#.
Some articles on it:
https://qawithexperts.com/article/c-sharp/lambda-expression-in-c-with-examples/470
https://exceptionnotfound.net/csharp-in-simple-terms-18-expressions-lambdas-and-delegates
http://dontcodetired.com/blog/post/Whats-New-in-C-10-Easier-Lambda-Expressions
In C# we cannot pass functions as parameters like we do in JavaScript. The workaround is using delegates.
When we want to parameterize the behavior instead of a value, we use delegates. Lambdas are practical syntax for writing delegates which makes it very easy to pass around behavior as functions.
This is perhaps the best explanations on why to use lambda expressions -> https://youtu.be/j9nj5dTo54Q
In summary, it's to improve code readability, reduce chances of errors by reusing rather than replicating code, and leverage optimization happening behind the scenes.

Categories

Resources