C# Lambda ( => )

C# equivalent of Lambda

You don't really need your own map and array methods. There is already the same functionality available, you just have to add using System.Linq; at the top of your file and you'll be able to use both Select, which is a projection method and ToArray which created an array from your collection. They are both extension methods set on IEnumerable<T>, so you can use them on almost any collection.

var centers = hexes.Select(x => me.hexToCenter(x)).ToArray();

is an equivalent of you JavaScript code:

var centers = Lambda.array(Lambda.map(this.hexes,function(hex) {
return me.hexToCenter(hex);
}));

What's the actual type of lambda in C#?

A lambda expression doesn't have a type. It cannot, because any type in the .NET world that it could have, would also hard-code the type of the lambda's parameters and result. Now consider:

x => x + 1

What type could x have? What type will the result be? There isn't any single answer, and the lambda expression can indeed be converted to Func<int, int>, Func<double, double>, and many other delegate types with different parameters. Giving a lambda expression a type would disallow such expressions. C# did want to allow such expressions, so was designed not to give such expressions any type.

Lambda for getter and setter of property

First of all, that is not lambda, although syntax is similar.

It is called "expression-bodied members". They are similar to lambdas, but still fundamentally different. Obviously they can't capture local variables like lambdas do. Also, unlike lambdas, they are accessible via their name:) You will probably understand this better if you try to pass an expression-bodied property as a delegate.

There is no such syntax for setters in C# 6.0, but C# 7.0 introduces it.

private int _x;
public int X
{
get => _x;
set => _x = value;
}

Confused by C# lambda expression

The => operator has exactly the same meaning in both cases: it creates a function whose parameter is the thing on the left, and whose return value is the thing on the right.

You wrote in a comment that the x in the first case is not a parameter as you understand it. That's not correct; it is a parameter in both cases here.

Here's your first example, again:

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b = a.FindAll(x => x>=5);
foreach (int x in b)
Console.WriteLine(x);

If you wanted to write this without using lambda notation, you would define a function somewhere, like this...

static bool MyCondition(int x)
{
return x >= 5;
}

...and then use that function as the argument to FindAll:

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b = a.FindAll(MyCondition);
foreach (int x in b)
Console.WriteLine(x);

The lambda notation is a shorter notation which allows you to define the function right where you use it.

Likewise, if you wanted to write your second example without using lambda notation, you'd define a function elsewhere, like this...

static int MyOperation(int x)
{
return x * 2;
}

...and pass your function as the argument to Select, like this:

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b1 = a.Select(MyOperation);
foreach (int x in b)
Console.WriteLine(x);

Understanding Lambda expressions and delegates

Delegates are methods that you can use as variables, like strings etc. For example you can declare a delegate method with one argument:

delegate void OneArgumentDelegate(string argument);

It doesn't do anything, much like an interface. If you have a method in any class with one argument like this:

void SomeMethod(string someArgument) {}

It matches the signature of the delegate, and thus can be assigned to a variable of its type:

OneArgumentDelegate ThisIsAVariable = new OneArgumentDelegate(SomeMethod);
OneArgumentDelegate ThisIsAlsoAVariable = SomeMethod; // Shorthand works too

These can then be passed as arguments to methods and invoked, like so:

void Main()
{
DoStuff(PrintString);
}

void PrintString(string text)
{
Console.WriteLine(text);
}

void DoStuff(OneArgumentDelegate action)
{
action("Hello!");
}

This will output Hello!.

Lambda expressions are a shorthand for the DoStuff(PrintString) so you don't have to create a method for every delegate variable you're going to use. You 'create' a temporary method that's passed on to the method. It works like this:

DoStuff(string text => Console.WriteLine(text)); // single line
DoStuff(string text => // multi line
{
Console.WriteLine(text);
Console.WriteLine(text);
});

Lambda expressions are just a shorthand, you might as well create a seperate method and pass it on. I hope you understand it better now ;-)

Where does the x come from in this lambda expression?

In simplest terms, x is a variable that you declare.

So it reads "x such that x is"... Whatever expression you are trying to convey based on the input and output parameter of your query.

To give you another example:

var sorted = list.Where(x => x.Name == "Foo").ToList();

This reads as "x such that x is equal to Foo". And this will return all list with Name property that is equal to Foo.

To further explain this, lets look into the one of the overloaded Enumerable method which is "Where". According to MSDN:

Sample Image

The actual syntax is:

Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate

To give another example lets declare a List of integer. Our goal is to get all even integers:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Now to query all integers who are even numbers, we will use the one of the overloaded version of Where extension methods, using lambda syntax. It says:

Sample Image

So the source here is the:

numbers.Where();

Since "numbers" variable is the IEnumerable of TSource.
TSource here is any IEnumerable of type "T" or any type of entity.

Now the last part is it accepts a Func. A Func is a predefined delegate type. It provides us a way to store anonymous methods in generalized and simple way. To further understand this, lets read it again. It says that it will accept a source, and will output a boolean result.

Sample Image

Now let's create a Func that accepts TSource, on this case, integer as our example and will output boolean result:

Func<int, bool> fncParameter = x => x % 2 == 0;

Now we can pass that into our:

numbers.Where

Which will be:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Func<int, bool> fncParameter = x => x % 2 == 0;
IEnumerable<int> result = numbers.Where(fncParameter);

Or in short:

ist<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> result = numbers.Where(x => x % 2 == 0);

How do you read lambda expressions?

Given that LINQ generally only works with IEnumerable objects, you could read s => as 'for each s in the IEnumerable'.

Update:
Revisiting this answer over 5 years on, I am deeply unsatisfied with it. Personally, nowadays I find myself considering it as "maps to" or I've seen "such that" which is also pertinent depending on the circumstance.

Difference between lambda and LINQ?

Language-Integrated Query (LINQ) is a set of features introduced in
Visual Studio 2008 that extends powerful query capabilities to the
language syntax of C# and Visual Basic

A lambda expression is an anonymous function that you can use to
create delegates or expression tree types. By using lambda
expressions, you can write local functions that can be passed as
arguments or returned as the value of function calls.

Linq uses Lambda expression in order to execute some of its functionalities.

Example:

new [] { "Dan", "Yossi", "Ben" }.Where(item => item.Length == 3);

Lambda expression: item => item.Length == 3

Linq: (from item in (new [] { "Dan", "Yossi", "Ben" }) where item.Length == 3)

C# Lambda expressions with Classes

Since you're using reference to Student, searching it in list and then retrieving its index doesn't make sense.
You are using Student instance anyway, so use LINQ's FirstOrDefault and retrieve object you are trying to modify (in this case, to change the SubjectScore).

You'd rather:

foreach(string[] lineItem in storedCSVData)
{

string fullName = lineItem[0] + " " + lineItem[1];

//Get student instance instead of index, since you would use it anyway
Student student = Students.FirstOrDefault(s => s.GetFullName().Contains(fullName));

//If there is no result, FirstOrDefault returns 'null'
if(student != null)
{
//Add using refernce instead of using index
student.SubjectScore.Add(
lineItem[4],
Convert.ToDouble(lineItem[5]));
continue;
}

Student storedStudent = new Student(lineItem[0],
lineItem[1],
lineItem[2] == "Yes" ? true : false,
Convert.ToInt32(lineItem[3]));

Students.Add(storedStudent);

}


Related Topics



Leave a reply



Submit