❔ Help me understand this lambda expression
var myKey = availableProducts.FirstOrDefault(x => x.Value == input).Key;
Console.WriteLine("Quantity: left " + myKey);
Im trying to understand how this code works (how it gets the key for the input value in a dictionary). Been searching the web but not really getting more clear.. mostly I dont understand the use of "x". Many thanks for any help!
80 Replies
the lamba is basically just a function that takes a
KeyValuePair<TKey, TValue>
and returns a bool
x
is the parameter name chosen, u could use also any other valid name for that.
if u would write the lambda as function manually (lets assume that both the TKey
and the TValue
are int
s for simplicity), it would look like this:
FirstOrDefault()
is a LINQ extension method on IEnumerable<T>
and takes a Func<T, bool>
as parameter
Dictionary<TKey, TValue>
implements this interface as IEnumerable<KeyValuePair<TKey, TVAlue>>
so it results in the Func<KeyValuePair<int, int>, bool>
from the exampleSorry for a probably stupid question, but what is a LINQ extension method?
do u know what extension methods are in general?
An extension method is a method that's added to the class from outside of the class
not really :/
Syntactic sugar over static methods, really
LINQ is a collection of such methods that extend the
IEnumerable
why is it added from outside the class?
Because you can't always just modify the class itself
You can't modify
int
to add new methods, can you?
But you can write an extension method for int
yeah u can basically "add methods" to another class
this would print
HELLO WORLD
and it looks like the method is part of the string
classwhat is meant by "modifying int" , in this context?
I think Im getting it
Well,
int
is a struct
That has value, properties, and what not
You can't just edit the source code of .NET standard library to add new methods to that int
structI also have a really hard time understanding exactly what a struct is, which probably makes it all even harder
Funky class
For all intents and purposes
LINQ is a powerful collection of such extension methods to simplify handling a lot of data the same way
so, FirstOrDefault is an extented method
yes
on the enumerable interface?
yep
which the dictionary implements?
correct
but why is it called a lambda function?
The name "lambda" comes from math, IIRC
You can call it an "anonymous function"
Both names are correct
I prefer Anonymous functions.
okay! but is there any point in making it anonymous? could it also be written non-anonymous?
Sure
Yes.
I prefer not using anonymous functions, I focus on readability.
its actually lambda "expression", a lambda on its own isnt a complete function, it always needs a delegate type to be assigned to. no matter if thats a method parameter like in the
FirstOrDefault()
case or if its a local variableYou can use not-anon functions, but it will just uselessly bloat your code
but if the lambda uses parameters (keyValuePair<TKey, TValue) and returns a bool, is it not a function?
Why write
and
when you can write
Why would it not be?
the type here defines what the lambda is mapped to
its a
Func
delegate, that takes two int
s (first two generic parameters) and returns an int
(last one)@ZZZZZZZZZZZZZZZZZZZZZZZZZ what @cap5lut wrote a bit earlier! that it isnt completely a function
"its actually lambda "expression", a lambda on its own isnt a complete function, it always needs a delegate type to be assigned to. no matter if thats a method parameter like in the FirstOrDefault() case or if its a local variable"
It’s still a function.
its not a function on its own, it only makes sense in combination with a delegate type
and what is a delegate type 😅
A type that describes the function
it basically defines a method signature/method type, return type and its parameter list
Func<int, string, string>
for example would be a function that takes two strings and returns an intlike the actual function name? would that be the delegate?
I think we're getting way deeper into it than necessary lol
delegate int LengthGetter(string value)
would be a delegate declaration
which can then be later used:
LengthGetter lengthGetter = str => str.Length;
ok, I think I need to read up on a few things, haha
but this is what Im getting: FirstOrDefault is an extended method from the enumerable interface which the dictionary implements
*extension
*IEnumerable
But yes
and as a PARAMETER, a lambda expression is used (also called an anonymus function)
Yep
stupid question again, but
why must a lambda expression or anonymous function be used?
its simply better this way, because the user of the method can write the actual check for it
its the x I dont understand :/
It's "each element of the collection"
Think of it as a
foreach
loop
With the check inside of itmaybe better to write the code out a bit:
this would be an example implementation
Thank you! Im getting closer now 😅 buuut, what about it makes it a foreach loop?
predicate(element)
is basically calling the delegate/ur lambda like any other method as wellis it the lambda that works as a loop?
and as u can see im passing the element to it
No, the inside of the method
ah now I see!!
The method itself loops over all elements of the collection, and returns whichever element matches your lambda
the FirstOrDefault already contains an actual ForEach
and x is = var
?
x
is the parameter of the lambda/delegate
public delegate TResult Func<TParameter, TResult>(TParameter parameter);
<--- that parameterAngius
REPL Result: Success
Result: string
Compile: 663.692ms | Execution: 83.204ms | React with ❌ to remove this embed.
Here's a way simplified example
soo x is the parameter used in the anonymous function/expression.
correct
and the anonymous function doesnt really do anything else then define the x as parameter. The only thing that does anything is the FirstOrDefault function
So you could say that the anonymus function is a parameter to the FirstOrDefault function
It most certainly is
Ok, thank you all very much 😄 I have some things to consider now, but I really appreciate you taking the time 😍
When in doubt, use the debugger and go through the code step-by-step to see what it does and when
yeah I try to, but it gets difficult to follow sometimes 😅
a delegate is a data type to pass functions around as variables and to call them.
the crucial point here is that they merely define the parameter list (count and type) and the return type itself
lambdas are syntax sugar to write anonymous functions, so u do not have to write a whole new method and pass that to the delegate parameter/variable
in ZZZZZZZZZ's example, without lambdas it would become quite more verbose
instead of just calling
GetMatching(arr, str => str.Length == 3)
u would have to write a new method and pass that:
this will quickly become quite bloaty if u would have too write a lot of these methods
(imagine u want to use GetMatching()
to get the first element with a length of 3, then the first with the length of 4 nd the first with the length of 5, this would mean 2 more functions really similar to HasLengthOfThree()
)
this is a lot simplier to read:
Im copying all of your replies into my notepad! very useful and important topics to cover, I am understanding
so delegates are methods used as variables
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions covers all of this also and is probably better phrased
Lambda expressions - Lambda expressions and anonymous functions - C#
C# lambda expressions that are used to create anonymous functions and expression bodied members.
therefore, in this context, the lambda IS a delegate?
a delegate is a method type, just like
int
is a number type
a lambda is just a short hand version to specify the value of such a typeso lambda is an example of a delegate?
yep (well in detail its a bit complexer, but this would confuse right now more than it would help)
ok, thanks again!! Im going to read through everything again in further detail, but I think its getting clearer
oh and since c# 10.0 lambdas have a natural type now, so what i earlier said:
its actually lambda "expression", a lambda on its own isnt a complete function, it always needs a delegate type to be assigned tois not true anymore
okay! thanks for clarifying, don´t think its super important for me at the moment, still trying to understand the very basics
this will help u understand more about it and some LINQ as well.
https://learn.microsoft.com/en-us/dotnet/csharp/linq/write-linq-queries
they describe method syntax and query syntax, ignore the latter for now, i dont think its used that often anymore
Write LINQ queries in C# - C#
Learn how to write LINQ queries in C#.
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.