The first part makes sense but it's the part in the brackets I don't understand.
What are you seeing here is a lambda expression. It's a very special anonymous delegate.
Is it mostly LINQ?
Enumerable.SingleOrDefault
is a LINQ method, but the lambdas are something independent of LINQ; they just make LINQ incredibly more friendly then it otherwise would be.
Now, to get specific IEnumerable<Subject>.SingleOrDefault(s => s.ID == ID)
returns the unique instance of Subject
in the IEnumerable<Subject>
that matches the predicate s => s.ID == ID
or it returns null
if there is no such instance. It throws an exception if there is more than one such instance. At compile-time s => s.ID == ID
is translated into a full-blown delegate the eats objects of type Subject
and returns a bool
that is true
if and only if s.ID
is equal to ID
.
How can we use s
without declaring it?
The =>
is the lambda operator. It basically separates the left-hand side of the lambda expression from the right-hand side. The left-hand side are the input variables. It's equivalent to the parameter list in an explicitly-defined method. That is s
in the lambda expression plays the role of s
below:
public bool Predicate(Subject s)
It's just that you don't have to declare the type of s
as the compiler will infer it.
The right-hand side the lambda body. It's equivalent to the body below
public bool Predicate(Subject s) {
return s.ID == ID;
}
What is more, you don't have to declare the return type; the compiler will infer that to.
So, in the end it is as if you did the following:
class MyPredicate {
public string ID;
public bool Predicate(Subject s) {
return s.ID == this.ID;
}
}
Then:
// elements is IEnumerable<Subject>
// ID is string
MyPredicate predicate = new MyPredicate();
predicate.ID = ID;
elements.SingleOrDefault(predicate.Predicate);
The nice thing is the compiler just automatically spits this out for you when you use a lambda expression.