views:

181

answers:

6

I know what this code is doing but I'm not sure on the syntax. It doesn't seem to conform to a "standard" format. Is it mostly LINQ?

return db.Subjects.SingleOrDefault(s => s.ID == ID);

The first part makes sense but it's the part in the brackets I don't understand. How can we use s without declaring it? And how are we putting logic into a method call?

+6  A: 

It is called a Lambda Expression. See here for an explanation. Lambda Expressions (C# Programming Guide)

Refracted Paladin
+6  A: 

It's the C# 3.0 compiler working some magic for you.

That statement gets compiled into a delegate, and is equivalent to:

return db.Subjects.SingleOrDefault(delegate(s) { return s.ID == ID }); 

It's called a lambda expression since you don't need to formally declare the parameters, they are inferred by the C# compiler.

codekaizen
+14  A: 

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.

Jason
@Jason: Nevermind, honestly though, very thorough answer.
Refracted Paladin
Thanks for the great explanation.
Mike
Great answer! really top stuff! +1
Alastair Pitts
@Jason: very well explained the lambda expression. Wonder if you can post it as a separate q )
balalakshmi
+1  A: 

That's a Lambda Expression.

Leif
+4  A: 

I think your confusion lies around the expression s => s.ID== ID. This is a lambda expression. It simple terms it's a way of definining an inline function.

In this case the text to the left side of the => is the argument list. So s is declared by virtue of being in it's position. The right side of the => is the expression executed. In this particular context the lambda will be run on every element in the collection and the code will assert there is one value which meets the expression executed by the lambda.

JaredPar
+1  A: 

s before => declares a variable with type of structure element (type contained in Subjects variable EDIT: Other functions works with more arguments ie. Join) that goes in the right part ( after => ). Logic comes from function. If you call SingleOrDefault (lookup in docs) it will return SINGLE element if satisfy condition or NULL. There are many functions in LINQ that u can use (ie. First(), Where(), ...). Hope that helps.

zveljkovic