Reputation: 127
There is a class named Student
which has the properties Id
, Name
and Phone
.
In a UI form there is a list of Student
in the following way:
List<Student> students=new List<Student>();
and finally there is a code for dataGridview_Cellclick
event, where the below code is used:
string id = dataGridview.Rows[e.RownIndex].Cells[0].Value.ToString();
Student aStudent = students.Find(i=> i.Id== id);
What does the students.Find(i=> i.Id== id)
do? What does it mean? What is the meaning of =>
sign? How does it work?
Upvotes: 7
Views: 255
Reputation: 13177
List<T>
defines a method Find(Predicate<T> match)
.
Predicate<T>
is a delegate which can refer to any method that matches its signature
bool Predicate(T param)
In your case you are calling the Find
method on a list of students List<Student>
so the Find
method expects a function that matches the following signature:
bool MyFindMethod(Student param)
You could define such a method in your class like so:
bool MyFindMethod(Student param)
{
// Logic goes here
}
and pass it to your Find
method like this:
students.Find(MyFindMethod)
The method you are using is small and simple so the overhead of creating a method in your class is not worth it so lambda expressions allow you to define the same method in a very concise way.
s => s.Id == id
is equivalent to:
bool AnonymousMethod(Student param)
{
return s.Id == id;
}
The item(s) on the left hand side of the =>
operator are the parameters that are passed to the method and the items on the right hand side of the =>
operator is the method body.
Note that the compiler is smart enough to work out that the parameter (s
in my example) is of type Student
so this does not need to be specified.
If you had a list of another type E.G.
public class Customer
{
public string Name { get; set;}
}
public IList<Customer> customers = new List<Customer>();
then the compiler would infer that the parameter was of type Customer
rather than student.
customers.Find(c => c.Name == name);
Note that the parameter can be named anything you want but is usually kept to a single letter to keep the expression concise.
If you understand all of this you then you will see that your code
students.Find(i => i.Id == id)
is basically calling a method that takes a Student
as a parameter and evaluates it to see if it matches the criteria on the right hand side of the =>
operator. If the parameter meets the criteria (that is, if the students Id
matches the id
variable) then the expression will return true. This tells the Find
method that it has found a match and this object will be returned.
I answered a similar question here which is related to WPF but an example in a different context might help your understanding.
Upvotes: 0
Reputation: 1825
=> is a goesto operator and this expression is lambda expresion
See msdn
Upvotes: 1
Reputation: 3996
students.Find(i=> i.Id== id)
do? The situation is this. You have a list of Student objects and the id of the student you are interested in. If the Student objects were stored in a collection you had defined yourself that has a Find method that takes an id and returns the student with that id, your code would look like this:
Student aStudent = students.Find(id);
However, when Microsoft defined the generic List collection, they could not possibly know how it will be used -- and they did not want to know. They wanted to give you the opportunity to use it with Student object or any other kind type you could think of. But that meant that they had to give you a way to find the elements you are after by providing the information about your problem that only you know. In this particular instance, you know that you are looking for a Student object stored in the students lists that had an Id field that matches the id you have. If I gave you an object, let us call it i
, you would be able to tell me if it is the one you are looking for by performing the following check:
i.Id == id
If I gave you an object called student
, you would be able to perform the test student
you would be able to tell me if it was the one you are after by performing the test
student.Id == id
(If you did not have the id but some other information that uniquely determines a Student object (i.e. a key) you would want to specify a different condition. Flexibility is important!)
So, now we reach the next question.
What does it mean?
Let's create a convention. You will determine what you want to call the student object and you will provide an appropriate check that picks the student you are after. You put the identifier that will represent that student on the left of =>
and the check condition on the right. Thus you can have something like:
student => student.Id == id
or if you prefer to refer to the student object under discussion i
instead of student
then you can write
i => i.Id == id
Now take a look. What is this? It is something that given a Student object returns a bool. It is a function!
What is the meaning of => sign?
It is an operator that defines a function. The argument is on the left hand side and the body is on the right hand side.
How does it work?
Suppose you wanted me to write a function that takes a List argument and a function such as the one we are discussing and returns the matching student without using the Find method. I would probably write something like this.
Student FindStudent(List students, Func match) { foreach(Student st in students) if(match(st)) return st; return st; }
You will probably find everything quite familiar, except, I guess, the type Func which you can imagine is a type of functions from Students to booleans. I could also have used Predicate, which you can guess is a type for predicates on Students.
However, you need not need me to write this or to write this yourself because Microsoft has already done this for us. The code Microsoft wrote for the Find()
of the List<T>
class looks very much like the above.
Hope that helps!
This should cover everything you have asked. But to get a broader picture you may want to have a look also at:
A few parting notes that may help you:
Upvotes: 1
Reputation: 236188
This is a goes to
operator (or lambda operator), which used in lambda expressions (anonymous methods creation) to separate input variables from lambda body.
In your sample students.Find(i => i.Id== id)
input variable i
goes to lambda body i.Id == id
(i.e. passed as a anonymous method parameter).
Also take a look on on List<T>.Find
method, which you are using. It accepts predicate of type T
, which in your case will be Predicate<Student>
. Predicated is a delegate, which represents method that defines a set of criteria and determines whether the specified object meets those criteria. It has following signature:
public delegate bool Predicate<in Student>(Student obj)
So, you need to pass a method, which accepts a student object and returns a bool. You can create normal named method for this:
private bool IsStudentHasIdEqualTo5(Student s)
{
return s.Id == 5;
}
And use it this way:
Student aStudent = students.Find(IsStudentHasIdEqualTo5);
But you need to verify for different id values. There is two options - either create field in your class, which will be available inside student predicate method, or create class, which will have both this method and field:
class StudentSearcher
{
private int _id; // capture id
public StudentSearcher(int id)
{
_id = id;
}
// method has same signature as bool Predicate(Student obj)
public bool VerfyId(Student s)
{
return s.Id == _id;
}
}
Now you can use this named method and provide different id
values for student verification:
var searcher = new StudentSearcher(id);
Student aStudent = students.Find(searcher.VerfyId);
But creating such methods and classes for each search is not very efficient. This is why we have delegates (and lambdas). Instead of declaring new named method, you can create method without name (anonymous) exactly in place where you need it, and compiler will generate usual named method for you:
Student aStudent = students.Find(delegate(Student s) {
return s.Id == id;
});
Exactly same code could be written in lambda syntax (delegate keyword omitted, parameter type inferred, goes to
operator used to separate parameter and method body, return keyword also omitted):
Student aStudent = students.Find(s => s.Id == id);
The magic here is that compiler will generate class like one shown above behind the scene. That class will have method with predicate signature, and also it will have field for capturing id
to search for.
Upvotes: 3
Reputation: 10995
The lambda operator separates the function argument(s) from its body.
(arg1,arg2...argn)
=>
{
//body
}
The body could also be without parenthesis.. but it is still a "body".
(arg1,arg2..argn) => 1 ;
Student aStudent = students.Find(i=> i.Id== id);
Find is a Linq method that takes a lambda expression.
It will go through each element in students.
The element is represented by i
- although student
would make more sense - and is passed into the "body".
If i.Id==id
the Find method returns the student
element.
Upvotes: 1
Reputation: 5977
They are call Lambda Expressions...Lambda expressions use special syntax. They allow functions to be used as data such as variables or fields. The lambda expression syntax uses the => operator. This separates the parameters and statement body of the anonymous function.
You can this of it as "Goes to".
The => operator can be read as "goes to" and it is always used when declaring a lambda expression. A lambda expression allows you to use a function with executable statements as a parameter, variable or field.
See this link on MSDN to understand it better.
Upvotes: 4