Supposing I have a string which I want to convert to an integer, I would do
int i;
int.TryParse(someString, out i);
Now I would like to do the same in a Linq query:
int i;
var numbers =
from s in someStrings
where int.TryParse(s, out i)
select i;
But this refuses to compile with the error
CS0165 Use of unassigned local variable 'i'
It compiles and works as intended when I initialize i to an arbitraty value. But why do I have to?
The query expression is translated into:
var numbers = someStrings.Where(s => int.TryParse(s, out i))
.Select(s => i);
Now, we know that the delegate created from the lambda expression for the Where call will be executed before the delegate created from the lambda expression for the Select call, but the compiler doesn't. And indeed, you could easily write your own extension method that didn't obey that:
public static IEnumerable<T> Where<T>(
this IEnumerable<T> source,
Func<T, bool> predicate)
{
// I can't be bothered to check the predicate... let's just return everything
return source;
}
At that point, with the normal Select call, your delegate returning i would be executed without every assigning a value to it.
Basically, the definite assignment rules are deliberately quite conservative, avoiding making any assumptions about what methods do etc.
This compiles to a pair of lambda expressions that are passed to Where() and Select().
The compiler does not know what Where() and Select() do, and cannot prove that Where()'s lambda will always run before Select().
The compiler cannot determine until runtime whether or not there will be any records returned. So in order for i to have a determined value, one must be explcitly assigned. Just think "what would i be if my Query returned no rows ?"
Related
This question already has answers here:
Understanding how lambda expression works [closed]
(4 answers)
Closed 3 years ago.
[Route("{year:min(2000)}/{month:range(1,12)}/{key}")]
public IActionResult Post(int year, int month, string key)
{
var post = _db.Posts.FirstOrDefault(x => x.Key == key);
return View(post);
}
Hi,
I'm doing this in ASP.NET Core with C#.
Vague part for me is this: _db.Posts.FirstOrDefault(x => x.Key == key);
So what I'm guessing is that:
execute FirstOrDefault method.
parameter x is passed (I don't what it is being passed exactly though).
then, compare x.Key with key
what is next step?
parameter x is passed (I don't what it is being passed exactly though).
No, this does not happen. What is passed is an expression defining an anonymous function. Such expressions, when using the => operator, are commonly called lambda expressions. x is the part of the expression which determines how the function is called. It's a placeholder for the input variable used by the function expression.
It will help you understand if I give you a pretend version of how the FirstOrDefault() method might be implemented:
public T FirstOrDefault<T>(this IEnumerable<T> items, Func<T, boolean> predicate)
{
foreach(T item in items)
{
if(predicate(item)) return item;
}
return default(T);
}
Some things to understand in that code:
this in front of the first parameter turns the function into an extension method. Instead of calling the method with two arguments, you skip the first argument... call it with only the second argument as if it were a member of the type from the first argument. ie, _db.Posts.FirstOrDefault(foo) instead of FirstOrDefault(_db.Posts, foo).
The key variable in the expression is called a closure. It is available as part of the predicate() function inside this method, even though it's not passed as an argument. This is why the predicate(item) call is able to determine true or false with only item as an input.
The predicate() function call within this method was passed as an argument to the method. That is how the x => x.Key == key argument is interpreted; it becomes the predicate() method used by the FirstOrDefault() function. You can think of it as if predicate() were defined like this:
bool predicate(T x)
{
return x.Key == key;
}
The C# compiler makes this translation for you automatically, and even infers the correct run-time type for T and automatically handles scope for the key closure.
The other answers are close, but not completely correct.
I assume that _db is an Entity Framework DbContext, and _db.Posts is a DbSet<Post>.
As such the .FirstOrDefault() method you are seeing is actually an Extension method and the x => x.Key == key part is an Expression tree.
What happens behind the scenes is that the call to _db.Posts.FirstOrDefault(x => x.Key == key) is translated to a SQL statement like SELECT TOP(1) Key, Content, ... FROM posts WHERE Key = #key, the result of which is mapped into a Post entity.
There are a lot of language features at play to make all this work, so let's have a look!
Extension methods
Extension methods are static methods, but can be called like instance methods.
They are defined in static classes and have a 'receiver' argument. In the case of FirstOrDefault the extension method looks like this:
public static class Queryable {
public static T FirstOrDefault<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate = null) {
// do something with source and predicate and return something as a result
}
}
It's usage _db.Posts.FirstOrDefault(...) is actually syntactic sugar and will be translated by the C# compiler to a static method call a la Queryable.FirstOrDefault(_db.Posts, ...).
Note that extension methods are, despite the syntactic sugar, still static methods do not have have access to their receiver's internal state. They can only access public members.
Delegates
C# has support for pseudo-first-class functions, called delegates. There are several ways to instantiate a delegate.
They can be used to capture existing methods or they can be initialized with an anonymous function.
The most elegant way to initialize a delegate with an anonymous function is to use lambda style functions like x => x + 10 or (x, y) => x + y.
The reason you don't see type annotations in these examples is that the compiler can infer the types of the arguments in many common situations.
Here is another example:
// This is a normal function
bool IsEven(int x) {
return x % 2 == 0;
}
// This is an anonymous function captured in a delegate of type `Func<T1, TResult>`
Func<int, bool> isEven = x => x % 2 == 0;
// You can also capture methods in delegates
Func<int, bool> isEven = IsEven;
// Methods can be called
int a = IsEven(5); // result is false
// Delegates can be called as well
int b = isEven(4); // result is true
// The power of delegates comes from being able to pass them around as arguments
List<int> Filter(IEnumerable<int> array, Func<int, bool> predicate) {
var result = new List<int>();
foreach (var n in array) {
if (predicate(n)) {
result.Add(n);
}
}
return result;
}
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var evenNumbers = Filter(numbers, isEven); // result is a list of { 2, 4, 6 }
var numbersGt4 = Filter(numbers, x => x > 4); // result is a list of { 5, 6 }
Expression trees
The C# compiler has a feature that allows you to create an Expression tree with normal-looking code.
For example Expression<Func<int, int>> add10Expr = (x => x + 10); will initialize add10Expr not with an actual function but with an expression tree, which is an object graph.
Initialized by hand it would look like this:
Expression xParameter = Expression.Parameter(typeof(int), "x");
Expression<Func<int, int>> add10Expr =
Expression.Lambda<Func<int, int>>(
Expression.Add(
xParameter,
Expression.Constant(10)
),
xParameter
);
(which is super cumbersome)
The power of expression trees comes from being able to create, inspect and transform them at runtime.
Which is what Entity Framework does: it translates these C# expression trees to SQL code.
Entity Framework
With all of these features together you can write predicates and other code in C# which gets translated by Entity Framework to SQL, the results of which are "materialized" as normal C# objects.
You can write complex queries to the database all within the comfort of C#.
And best of all, your code is statically typed.
The x is the range variable of the object you called the function on. The same object you would get in foreach (var x in _db.Posts) It then iterates through that collection looking for x.Key == key and returns the first object that fulfills that. So that function will return the first object in db.Posts where Key == key
edit: corrected term
Your lambda expression with FirstOrDefault is equivalent to the following extension method
public static Post FirstOrDefault(this YourDBType _db, string Key)
{
foreach(Post x in _db.Posts)
{
if(x.Key == Key)
{
return x
}
}
return null
}
X isn't an parameter, its just a shorthand way of referring to the individual item in the collection you are working on like we would have in a foreach statement. The last step in your question is "either return the first Post that has the same key we are comparing against, or return the default value of a Post object (which is null for objects)"
I have the following filter :
Expression<Func<Employee, bool>> fromDateFilterFourDays = z => EntityFunctions.TruncateTime(z.FiringDate) >= EntityFunctions.TruncateTime(DateTime.Now.AddDays(-4));
Expression<Func<Employee, bool>> fromDateFilterSixDays = z => EntityFunctions.TruncateTime(z.FiringDate) >= EntityFunctions.TruncateTime(DateTime.Now.AddDays(-6));
How can I make a delegate out of this filter ?
I don't want to create a variable for each given number , i.e. for four days or six days .
My understanding is that you want to:
Take in two parameters to the delegate, the employee and the number of days.
Compile that expression into a delegate.
The first part can be done by adding the days to the parameter list:
Expression<Func<Employee, int, bool>> fromDateFilter = (z, n) => EntityFunctions.TruncateTime(z.FiringDate) >= EntityFunctions.TruncateTime(DateTime.Now.AddDays(n));
The second by using the Compile method:
var del = fromDateFilter.Compile();
// use it
del(employee, -4);
You can easily turn Expression<Func<...>> to Func<...> by using Compile method.
However, keep in mind that the sample expressions you provided will not work, because they are using Canonical Functions which are just placeholders for mapping the corresponding database SQL functions, and will throw exception if you try to actually evaluate them (which will happen with Func).
From the other side, if the question is actually how to parametrize the sample expressions, it could be like this
static Expression<Func<Employee, bool>> DateFilter(int currentDateOffset)
{
return e => EntityFunctions.TruncateTime(e.FiringDate) >= DateTime.Today.AddDays(currentDateOffset);
}
This is done by calling the Invoke() method:
fromDateFilterFourDays.Invoke(employee);
Or you can Compile() the expression to a func and then call the func:
var fromDateFilterFourDaysFunc = fromDateFilterFourDays.Compile();
fromDateFilterFourDaysFunc(employee);
It's amazing how little information there is on this. I found tons of tutorials explaining LINQ, but they don't explain this particular operator:
var Results = UserFavoritesContext.UserFavorites.Select(color => color.FavoriteColor);
"x => x.y"
Can someone please explain how this works? I get the general syntax and am able to use it to make queries, but it's like doing something without knowing what you're doing.
Suppose you have a list of people, and you want to iterate over them. You would write something like:
foreach(var person in people)
{
//do something to person
}
Note how you yourself chose the name person. It could've been any word, but you basically said "process every single item of the list as my person variable".
Now look at this LINQ query:
filteredPeopleList = people.Where(person => person.Name == "John");
Again, you basically chose person as a placeholder name for every object in the original list (one at a time). The above Linq query is equivalent to
foreach(var person in people)
{
if(person.Name == "John")
{
filteredPeopleList.Add(person);
}
}
To me, x => x.y is basically saying "for every variable we process (let's call it x), please perform the following operation on it (x.y, get the y property)"
I hope that explains it.
Edit
As a commenter who now deleted his comment mentioned, this isn't exclusively used in LINQ. A lambda expression doesn't have to iterate over an IEnumerable, it can be used to process a single item.
However, LINQ is by far the most common place to encounter lambdas, and I find their use very similar to the foreach loop, which is why I picked this example.
The => operator is used in lambda expressions.
The best way to think of this is a type of syntax for writing a function, where the left side of the operator is the parameters for the function and the right side is the body of the function e.g. this is a valid use of a lambda expression where its being used like a function:
Func<int, int> incrementFunction = i => i + 1;
int incrementedNumber = incrementFunction(1);
The name i in this case is an arbitrary variable name e.g. just like you would name a functions input parameter. Notice I didnt need to declare the input parameters type because the compiler will infer it. Also notice I dont need to include the "return" keyword or enclose the function body in a code block. It doesn't necessarily need any parameters either e.g.
Action myAction = () => Console.Write("something");
myAction();
When you use it in a linq expression, think of it as though the lambda function is being called on every element in the collection (which I believe is exactly what happens with linq to objects).
It's the syntax of a Lambda expression. If it helps you to remember... in a nutshell, the argument to pass (the parameter) is on the left of the => and the method(s) that use it are on the right hand side of it.
I hope this short summary explains it enough :)
That is a lambda expression, and it can be used as a selector from an object
You can conditionally select (or another operation orderby, count, etc) when the expression is true. For example:
Say you had a list of people and their details: ID, Name, City and Profession.
You could select a single person by using lambda to search for their specific ID:
public Person GetByID(int id)
{
Person selectedPerson = people.SingleOrDefault(person => person.ID == id);
return selectedPerson;
}
Same could be applied for a select on a city, this would be:
public List<Person> GetByCity(string city)
{
List<Person> selectedPeople = people.where(person => person.City == city);
return selectedPeople;
}
The lamda expression is where you place your operation variable, so in these cases the condition upon which you select the data. You can use it as a orderby variable much in the same way, in the next example I use two lamdas to perform two seperate functions
public List<Person> GetByCity(string city)
{
List<Person> selectedPeople = people.where(person => person.city == city)
.OrderByDescending(person => person.Name);
return selectedpeople;
}
I hope this helps at all
x => x.y is Lambda Expression introduced with C# 3.0. The general syntax is
parameter => executioncode
The Lambda Expression has 3 parts:
x on left hand side is the parameter.This can be a variable,delegate or an anonymous function.
=> read as "goes to", which acts as separator
x.y is an Expression to be evaluated.
For example, the lambda expression x => x * x specifies a parameter that’s named x and returns the value of x squared (source: MSDN).
Hope this would help you.
They're called Lamda expression:
https://msdn.microsoft.com/en-us/library/bb397687.aspx
var Results = UserFavoritesContext.UserFavorites.Select(color => color.FavoriteColor);
is similar to:
List<UserFavorite> Results = new List<UserFavorite>();
foreach(var item in UserFavorites)
{
Results.Add(item.FavoriteColor);
}
This is not specific to Linq.
It is the way you write a lambda expression.
The arrow => is the delimiter between your lambda parameters and its body.
Is it mandatory that lambda expression need to use when LINQ will be used, or are lambda expressions optional?
In lambda expressions, the sign => is always used. What does it mean?
customers.Where(c => c.City == "London");
Here c => is used but why?
What kind of meaning of using c =>. Please discuss in detail because I don't know lambda.
No, you don't have to use a lambda expression. For example, your Where example could be written as:
private static bool IsLondon(Customer customer)
{
return customer.City == "London";
}
...
var londoners = customers.Where(IsLondon);
That's assuming LINQ to Objects, of course. For LINQ to SQL etc, you'd need to build an expression tree.
As to why "=>" is always used in a lambda expression, that's simply because that's the way the operator is written - it's like asking why "+" is used for addition.
A lambda expression of "c => ..." is effectively giving the lambda expression a parameter called c... in this case generic type inference provides the type of c. The body provides either an action to perform or some calculation to return a value based on c.
A full-blown description of lambda expressions is beyond the scope of this answer. As a blatant plug for my book, however, they're covered in detail in chapter 9 of C# in Depth.
The lambda expression
c => c.City == "London"
is shorthand for something like
bool IsCustomerInLondon(Customer c)
{
return (c.City == "London");
}
It's just a very concise way of writing a simple function that returns a value. It's called an "anonymous function" because it's never assigned a name or a formal definition (the parameter types and the return type are inferred from the context).
(Actually, it's not just shorthand; lambda expressions are related to some other constructs called closures, which are very cool and powerful tools.)
Think about lambdas as anonymous of functions.
I'll try to explain it with following code.
public bool IsLondon(Customer customer)
{
return customer.City == "London";
}
Now we strip down function name and get rid of braces:
public bool Customer customer
return customer.City == "London";
We don't need return type, because compiler is able to deduce type from expression:
customer.City == "London";
In the same manner compiler knows about input type, so we don't need to specify it.
So basically, what we left with is
customer
return customer.City == "London";
And lambda syntax in c# is basically:
(parameter list) => "expression"
You can also write "multi-line" expressions, but then you have to surround your code with curly braces. Also you will need to use "return" statement, like you usually do.
Jon already answered,
but I'd like to add this.
In the example you have given, imagine Linq looping over all customers,
and c is simply a reference to each item in the enumerable:
var result = new List<Customer>();
foreach(var c in customers)
{
if (c.City == "London")
result.Add(c);
}
return result;
It's a variable like any other, it does not have to be a single named one,
but it's just a convention of some sort.
you do not need to use lambda expressions on Lİnq to sql or Entities; here is an alternative way of your code;
you code :
customers.Where(c => c.City == "London");
the other way;
var query = from cs in customers
where cs.City == "London"
select cs;
this is the another way. it is up to you.
Lambda and linq are quite separate. You can use one without using the other (there are parts of linq that depend on lambda expressions, but we want to keep it simple :-) )
A lambda expression is an anonymous
function that can contain expressions
and statements, and can be used to
create delegates or expression tree
types.
This was from MSDN. (http://msdn.microsoft.com/en-us/library/bb397687.aspx )
To make it short (it's much more complex) you can use a lambda expression to make a local function. what you put before the => (in your example the c) will be the parameter of the function. The return type is "discovered" by the C# compiler.
c => c.City == "London" is nearly equivalent to:
delegate (TheObjectTypeOfC c) {
return c.City == London
};
(the difference is that some lambda expression are delegates and also expressions, but please ignore this, you won't need it for some time)
If/when the compiler isn't able to infer the types of the parameters, you can force them: (MyObject p) => p.SomeProperty != null. Here you are telling the compiler that p is a parameter.
While here I showed you what are called "expression lambdas", you can even do "statement lambdas":
p => {
for (int i = 0; i < 10; i++) {
if (p.SomeProperty == 0) {
return true;
}
}
return false;
}
(I won't tell you what are the "behind the scenes" differences between expression lambdas and statement lambdas. If you want to know them, read the msdn page I pointed before)
No it is not necessary at all.
We have two ways to write LINQ queries.
One is query method and other is builder method. You only need to put lambda expression in case of builder method.
For example, if we want to find all those students from some Students object that have more marks than 70.
but we can do this thing in LINQ with following syntax
var data = from p in stdList
where p.marks > 70
select p;
or
var data = stdList.Where(p=>p.marks > 70);
later approach is builder method, in Where function, we are passing lambda expressions.
Lambda expressions are just short cuts of doing things you can always use LINQ queries but if you want to avoid whole query syntax for just applying a simple condition you can just use LINQ builder methods (which asks for lambda expressions) in lambda expressions, you always define some alias and then perform your operation.
As far as => operator is concerned, It works just like assignment operator.
For example:
(p) => p.Gender == “F”
It means “All persons p, such that person’s Gender is F”
In some literature this is called “predicate”. Another literature terminology is “Projection”
(p) => p.Gender ? “F” : “Female”
“Each person p becomes string “Female” if Gender is “F””
This is projection, it uses ternary operator.
Although i explained with very basic examples but i hope this would help you . . . :)
What is the exact use of AsEnumerable? Will it change non-enumerable collection to enumerable
collection?.Please give me a simple example.
From the "Remarks" section of the MSDN documentation:
The AsEnumerable<TSource> method has no effect
other than to change the compile-time
type of source from a type that
implements IEnumerable<T> to
IEnumerable<T> itself.
AsEnumerable<TSource> can be used to choose
between query implementations when a
sequence implements IEnumerable<T> but also has a different set
of public query methods available. For
example, given a generic class Table
that implements IEnumerable<T> and has its own methods such
as Where, Select, and SelectMany, a
call to Where would invoke the public
Where method of Table. A Table type
that represents a database table could
have a Where method that takes the
predicate argument as an expression
tree and converts the tree to SQL for
remote execution. If remote execution
is not desired, for example because
the predicate invokes a local method,
the AsEnumerable<TSource>
method can be used to hide the custom
methods and instead make the standard
query operators available.
If you take a look in reflector:
public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{
return source;
}
It basically does nothing more than down casting something that implements IEnumerable.
Nobody has mentioned this for some reason, but observe that something.AsEnumerable() is equivalent to (IEnumerable<TSomething>) something. The difference is that the cast requires the type of the elements to be specified explicitly, which is, of course, inconvenient. For me, that's the main reason to use AsEnumerable() instead of the cast.
AsEnumerable() converts an array (or list, or collection) into an IEnumerable<T> of the collection.
See http://msdn.microsoft.com/en-us/library/bb335435.aspx for more information.
From the above article:
The AsEnumerable<TSource>(IEnumerable<TSource>) method has no
effect other than to change the compile-time type of source from a type
that implements IEnumerable<T> to IEnumerable<T> itself.
After reading the answers, i guess you are still missing a practical example.
I use this to enable me to use linq on a datatable
var mySelect = from table in myDataSet.Tables[0].AsEnumerable()
where table["myColumn"].ToString() == "Some text"
select table;
AsEnumerable can only be used on enumerable collections. It just changes the type of the collection to IEnumerable<T> to access more easily the IEnumerable extensions.
No it doesn't change a non-enumerable collection to an enumerable one. What is does it return the collection back to you as an IEnumerable so that you can use it as an enumerable. That way you can use the object in conjunction with IEnumerable extensions and be treated as such.
Here's example code which may illustrate LukeH's correct explanation.
IEnumerable<Order> orderQuery = dataContext.Orders
.Where(o => o.Customer.Name == "Bob")
.AsEnumerable()
.Where(o => MyFancyFilterMethod(o, MyFancyObject));
The first Where is Queryable.Where, which is translated into sql and run in the database (o.Customer is not loaded into memory).
The second Where is Enumerable.Where, which calls an in-memory method with an instance of something I don't want to send into the database.
Without the AsEnumerable method, I'd have to write it like this:
IEnumerable<Order> orderQuery =
((IEnumerable<Order>)
(dataContext.Orders.Where(o => o.Customer.Name == "Bob")))
.Where(o => MyFancyFilterMethod(o, MyFancyObject));
Or
IEnumerable<Order> orderQuery =
Enumerable.Where(
dataContext.Orders.Where(o => o.Customer.Name == "Bob"),
(o => MyFancyFilterMethod(o, MyFancyObject));
Neither of which flow well at all.
static void Main()
{
/*
"AsEnumerable" purpose is to cast an IQueryable<T> sequence to IEnumerable<T>,
forcing the remainder of the query to execute locally instead of on database as below example so it can hurt performance. (bind Enumerable operators instead of Queryable).
In below example we have cars table in SQL Server and are going to filter red cars and filter equipment with some regex:
*/
Regex wordCounter = new Regex(#"\w");
var query = dataContext.Cars.Where(car=> article.Color == "red" && wordCounter.Matches(car.Equipment).Count < 10);
/*
SQL Server doesn’t support regular expressions therefore the LINQ-to-db providers will throw an exception: query cannot be translated to SQL.
TO solve this firstly we can get all cars with red color using a LINQ to SQL query,
and secondly filtering locally for Equipment of less than 10 words:
*/
Regex wordCounter = new Regex(#"\w");
IEnumerable<Car> sqlQuery = dataContext.Cars
.Where(car => car.Color == "red");
IEnumerable<Car> localQuery = sqlQuery
.Where(car => wordCounter.Matches(car.Equipment).Count < 10);
/*
Because sqlQuery is of type IEnumerable<Car>, the second query binds to the local query operators,
therefore that part of the filtering is run on the client.
With AsEnumerable, we can do the same in a single query:
*/
Regex wordCounter = new Regex(#"\w");
var query = dataContext.Cars
.Where(car => car.Color == "red")
.AsEnumerable()
.Where(car => wordCounter.Matches(car.Equipment).Count < 10);
/*
An alternative to calling AsEnumerable is ToArray or ToList.
*/
}
The Enumerable.AsEnumerable method can be used to hide a type's custom implementation of a standard query operator
Consider the following example. we have a custom List called MyList
public class MyList<T> : List<T>
{
public string Where()
{
return $"This is the first element {this[0]}";
}
}
MyList has a method called Where which is Enumerable.Where() exact same name. when I use it, actually I am calling my version of Where, not Enumerable's version
MyList<int> list = new MyList<int>();
list.Add(4);
list.Add(2);
list.Add(7);
string result = list.Where();
// the result is "This is the first element 4"
Now how can I find the elements which are less than 5 with the Enumerable's version of Where?
The answer is: Use AsEnumerable() method and then call Where
IEnumerable<int> result = list.AsEnumerable().Where(e => e < 5);
This time the result contains the list of elements that are less than 5