This is an example out of a book using northwind database. What is the => mean ?
Northwind db = new Northwind(#"Data Source=.\SQLEXPRESS;InitialCatalog=Northwind");
var orders = db.Customers
.Where(c => c.Country == "USA" && c.Region == "WA")
.SelectMany(c => c.Orders);
Console.WriteLine(orders.GetType());
why don't they just write
Where(c.Country == "USA" && c.Regian == "WA")
The part inside the parentheses of the Where() needs to be a function that takes a Customer and returns a boolean value (that's Func<Customer, bool> in C#'s type system).
It's most common to write that function using C#'s Lambda Expressions.
The c => part means "take the Customer that's passed in to you and call it c. Then with that value of c, compute this conditional. Without the c on the left side of the =>, the compiler would have no way of knowing what c refers to.
If they wrote this:
Where(c.Country == "USA" && c.Regian == "WA")
Where would you define what the variable c referred to? What if somewhere earlier in my code I had written:
var c = "this is a string";
This notation defines a lambda construct, where c => is bound to the delegate input expected by the Where function - in this case, c is bound to each row, and the function you run with c needs to return a boolean.
Note that you could have written a function like this:
public bool OnlyWA(Row c)
{
return c.Country == "USA" && c.Regian == "WA";
}
And then used it like this:
var orders = db.Customers
.Where(OnlyWA)
.SelectMany(c => c.Orders);
Here you don't need the c any longer because you're using a named function not a lambda variable. The only parameter to the function acts in place of the c. This is usually overkill for small functions, and further makes it harder to read as the small predicate function is moved away from its usage (and therefore contextual) location.
It's a lambda expression. It describes a function; the variables to the left of the arrow are parameters to the function. In this case, the function has one parameter, so there is a single variable to the left of the arrow.
Consider the "why don't they..." example you gave. Where is c declared? How does the compiler know what it represents?
You may wonder how the compiler knows the type of the c parameter, which it obviously does, because it allows you to call the Country and Region properties. This is accomplished with type inference. The Where method requires a delegate argument with a parameter whose type depends on the type of the sequence (Customers, in this case).
Since Customers is an IEnumerable<Customer>, the compiler expects a delegate with a single Customer parameter, and it therefore treats the single parameter of the lambda expression as a Customer variable.
=> is the lambda operator
See here: msdn
It is used in lambda expressions to separate the input variables on the left side from the lambda body on the right side. Lambda expressions are inline expressions similar to anonymous methods but more flexible; they are used extensively in LINQ queries that are expressed in method syntax.
Related
I have occasionally come across statements like this
school.Where(s => s.name == "foo")
Now I understand this is a lambda and I think I am comfortable with lambdas. I just started C# so I do have this question. In the statement
s => s.name == "foo"
how is the evaluation return being done to determine true or false. I do not see a return statement ? All i see is a comparison operation in the lambda body and nothing being returned. Can anyone please explain this to me.
In this form the return is implicit. The lambda returns whatever the expression returns. You could also write it like this:
s => { return s.name == "foo"; }
The reason why the return isn’t needed in the short form is because that’s how the language was designed. It makes things short and nice to use instead of forcing the developer to write unnecessary code.
The return statement is implied. If you were to add brackets around s.name == "foo" then you'd have to have a return. The compiler essentially creates a function to be called there for you. This is just syntax sugar. It's equivalent to creating a function yourself and passing that into the Where
Lambda can be defined in two ways:
with curly braces: then you will have to write body of a method, just like in a regular method, i.e. with returns, etc. Example
var lambda = (string param) => { return param.Length; };
without curly braces: then the method has to contain one line, which also be the result of a method. Example:
var lambda = (string param) => param.Length;
This is by design, to make one-line methods look nice and clean (especially in LINQ extensoin methods) :)
The returned value is always boolean and you can get it like below:
s=> {retutn s.name=="foo";}
I have this line of code, it works but I don't understand it:
Genres.Find(delegate (Genre genre) { return genre.Id == id; });
Genres is a list of genre(music)
What exactly is happening here?
C# provides two ways of defining delegates without writing a named method for it - the old anonymous method syntax introduced in C# 2.0, and the shorter lambda syntax introduced in C# 3.0.
Your code is the old way of writing this:
Genres.Find(genre => genre.Id == id);
This article describes the evolution of anonymous functions in C#.
Your Find method takes a predicate delegate. Depending on the version of .NET targeted by your code it may or may not be the System.Predicate<T> delegate, but its functionality is equivalent. An anonymous method in parentheses provides an implementation of your predicate, allowing you to pass arbitrary conditions to your Find(...) method.
It says, find the Genre (from the list Genres) which has the Id equal to the value from the variable id.
The keyword delegate says, that this is a kind of inline function which decides whether the check is true for each item or not. The beginning (Genre genre) says "given I would call each element genre in the loop, I can check each items' Id with its named variable Id". This is: genre.Id == id.
A modern approach would be the usage of lambdas like:
var x = Genres.Find(g => g.Id == id);
In this case g is your loop variable you can check against.
An intuitive way to see it:
Genres.Find( --- The CompareGenres function is being called from here --- );
bool CompareGenres(Genre genre)
{
return genre.Id == id;
}
Find accepts a Predicate < T >, T is the type of the parameter, in this case: you're passing an instance of Genre which is being supplied by the Find method.
"The Predicate is a delegate to a method that returns true if the object passed to it matches the conditions defined in the delegate."
So you're just passing a method as a parameter in the form of a delegate
Maybe I do not use the right terms here. But form an abstract point of view: The Find method here accepts a delegate as parameter. It allows you to implement the "find" algorithm (here comparing the id). It is flexible code you could also compare any other object of "genre".
I just started working on a project with an existing code base. While looking over the project, I found an odd lambda that I'm trying to understand.
Here's the code:
SomeFunction(x => () => new Y());
I don't understand...
why there are two => operators in the callback.
what is the purpose of the ().
For reference, here is the method signature of SomeFunction:
ISomeInterface<T> SomeFunction(Func<IXInterface, T> method);
The first lambda is returning a second lambda (a function) that returns a new object, in this case of type T. Recall that functions (i.e. delegates) are first-class objects in their own right.
In an ordinary lambda function, there is a lambda parameter that "encloses" the outer scope, as in this predicate:
x => x.SomeMember == true;
The () is simply a placeholder that says "I don't require a lambda parameter here, since I don't need to refer to the outer scope." (x) and (x, y) are also valid forms, so the () just means "no lambda parameters specified."
I have code like this
var results = (from c in Customers
join o in Orders
on c.Id equals o.CustomerId
join p in Products
on p.Id equals o.ProductId
select new
{
CustomerId = c.Id, // this is a GUID
OrderId = o.Id, // this is a GUID
ProductName = p.ProductName,
}).ToList();
Let's say I want to get a list of all customer Ids that orders a product that has name = foo
My problem is that because its an anonymous type, how can I refer product name in any Linq query that I want to run on results?
var filteredResults = results.Where(r => r.ProductName == "X");
The compiler's type inference takes care of it for you. The complete answer to your question:
var customerIds = results
.Where(r => r.ProductName == "X")
.Select(r => r.CustomerId)
.Distinct()
.ToList();
or
var customerIds = (from r in results
where r.ProductName == "X"
select r.CustomerId)
.Distinct()
.ToList();
EDIT
Some musings on type inference
To select the lengths from a sequence of strings called list, you can call Select either using classic static method syntax or as an extension method:
Enumerable.Select<string, int>(list, s => s.Length)
list.Select<string, int>(s => s.Length)
Thanks to type inference, you don't need the type arguments:
Enumerable.Select(list, s => s.Length)
list.Select(s => s.Length)
In this case, the compiler can prove that the type arguments are string and int by looking at the method arguments, and it supplies these type arguments on your behalf without your having to type them into the source code.
For anonymous types, you can't provide the first type argument, because the type doesn't have a name for you to use in the source code (that's what "anonymous" means, after all: "without a name"). (You can see therefore that anonymous types and type inference were both critical -- and closely related -- prerequisites to implementing linq in the first place.)
If you check out the IL for the anonymous type example above, you'll see that the compiler has in fact given the type a name (which contains characters that are illegal in C# identifiers). When you call Select, the compiler deduces from the type of the enumerable (IEnumerable<CrazilyNamedAnonymousType>) that the first type argument should be the anonymous type, and, as with the string example, it supplies that value on your behalf.
Within the method that generates this anonymous typed result, you can continue to refer to the results just as if you had defined a concrete type.
var customersWithFoo = results.Where(r => r.ProductName == "foo")
.Select(r => r.CustomerId);
If you are returning the original query result out of this method and then wish to query it further or otherwise programmatically access the elements, define a type.
class QueryResult
{
/* relevant properties */
}
And then project into that type in your original query, and return a sequence of that type from your method.
public IEnumerable<QueryResult> GetResults()
{
var results = ...
select new QueryResult
{
// properties
};
return results;
}
Following up on your comment:
I am confused about the scope of anonymous types
First let's clearly define "scope". The scope of a type is defined as the region of program text in which the type may be referred to by its unqualified name.
With that definition it is obvious what the scope of an anonymous type is. There is no region of program text in which the anonymous type may be referred to by its name because it does not have a name. Anonymous types don't have scope at all. You don't have to worry about its scope; it has no scope.
The fields of an anonymous type also have no scope, but for a different reason. Fields of an anonymous type have names, but it is never legal to refer to them by their unqualified names, so the scope of each field is empty.
I am not sure what will be visibility of this type within a method or class scope.
Again, let's clearly define our terms. The scope of an entity may include entities which define declaration spaces. Those declaration spaces may declare entities that have the same name as the original entity. Those entities have their own scopes, which may nest inside of the scope of the original entity.
In this situation, a more-nested entity may "hide" a less-nested entity. An entity which is not hidden in this manner is said to be "visible" at a particular textual location.
An anonymous type does not have a scope, and it obviously cannot be hidden by name because it does not have a name. Asking whether an anonymous type is "visible" or not is not a sensible thing to do; "visibility" only makes sense for things that have names.
My thinking is that given that this type is not declared anywhere, how can the compiler figure out which type I am talking about?
The compiler makes a note of every textual location in which you use an anonymous type within a program. If any two of those locations refer to anonymous types that have the same field names, the same field types and the fields come in the same order then those two locations are treated as usages of the same anonymous type.
The compiler can then emit one type for each of the unique anonymous types you used in your assembly. The details of how it does so are fascinating (*). I suggest that you poke around your assembly with ILDASM to see how we do it if you are interested.
If you make "the same" anonymous type -- same names, types and in the same order -- in two different assemblies then the anonymous types will not be treated as the same type. Anonymous types are not designed to be used across assembly boundaries.
(*) To me.
Anonymous types will show up in intellisense, just like "normal" types. At compile time, a concrete class is created that represents your anonymous type, so there is very little difference at runtime.
Here is querying from your results set:
var fooOrders = (from x in results
where x.ProductName == "foo"
select x.CustomerId);
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?
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.
It is called a Lambda Expression. See here for an explanation.
Lambda Expressions (C# Programming Guide)
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.
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.
That's a Lambda Expression.
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.