ā Deferred Execution or Forcing Immediate Execution
So I was reading the documentation on LINQ and I came across the two concepts i wrote in the title, now lets look at:
Now its pretty clear its deferred execution, we declare the query but its actually executed when the
foreach
is called. What I dont understand is why
Is considered Immediate execution, it still declares it and then triggers the query, in this case a foreach
internally but conceptually this is pretty much the same.
This though:
Calling .ToList
or To.Array
makes sense, you'd be executing the query in place and returning the result of the execution rather than saving the query to be executed later. Am I misinterpreting the documentation?182 Replies
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/introduction-to-linq-queries#forcing-immediate-execution
Just a heads up, I am aware that these technical details arent relevant to beginners. I've been writing C++ for a long time and just trying to understand all the C# details I read over, consider me a nerd š
First, I'd recommend using method aka fluent syntax instead of query syntax, makes it much easier to read and is generally what most of the community prefers.
second,
Count();
on an IEnumerable
forces executionYeah, it uses foreach internally
exactly
but I dont understand why a
foreach
explicitly after declaring the query is deferred execution
and this being any differentOh, they're not
That's what the documentation showed me though, did I misread?
I think you might have misinterpreted it yes.
this is the lazy part.
Because the query variable itself never holds the query results, you can execute it as often as you like.
or
var queyr = nums.Where(x => x%2 != 0);
yeahWait, so its about the fact that whenever you use these methods that use
forecah
you arent exposed
to the actual data
therefore its immediate execution
and its only deferred when you dont use these, and therefore are exposed to the queries data "raw"
so it has nothing to do with the "declarate query -> execute query" concept, rather how the source data is handled and what is actually exposed to the programmer?
that'd make sense, according to that logic this: int evenNumCount = evenNumQuery.Count();
is Immediate exection, while the first example wouldnt be.I don't follow, and I think you are still misunderstanding the docs.
let me boot up an IDE, 1 sec
take your time
Why is this "Force Immediate Execution" is my question I guess
I get that it uses foreach internally, but lets say I wrote the same count method without using the
.Count()
but using a simple foreach and counting up with each entry. That would be deferred execution then no?
no, don't associate the code example under each header with what the header says
what its trying to tell you is that the
IEnumerable<T>
(or IQueryable<T>
) types always use deferred execution. They don't execute on their ownAh okay, I see - I understand now
its only when you loop over it, or use a terminating method (Count, ToList, ToArray) etc
generally, if your method takes an IEnumerable and returns an IEnumerable, it will work with the deferred execution. There are ofc ways to break this, but its "generally" true
so its only immediate when you call it at the same place you declare the query
essentially
if you ever save a reference to the
IEnumerable<T>
created by a LINQ iterator, yesmakes sense
even if that is directly followed by an execution, your query is still there and can be executed again
yeah if you call count directly on it
u cant do it again later
as the results yield an
int
in that caseno you can, but it will be executed again
ie iterated again
var r1 = source.Where(x => x % 2 == 0).Count();
I'd have to restate the query here no, I am not declaring the query anywhere here I directly call .Count
?depends
look at r2
thats executing the "query" query again
yeah
even thou we already ran it when we did
count = query.Count()
that uses deferred
there is no option really
.Where is always deferred. But if you never save a reference to that iterator, and just consume it directly with an executor, you dont have multiple enumerations
so if you need the filtered data AND the count, then its always better to actualize the query to a list/array first, then access the count on that
Pobiega
REPL Result: Success
Console Output
Compile: 515.921ms | Execution: 107.421ms | React with ā to remove this embed.
oh, should have placed the select before the where. silly me
but whatever, you get the point
the console output we see here is from the iteration taking place in count, and then the iteration taking place in toArray
wait when using the Method Syntax you open with select
rather than having it at the end
I recall seeing its being the other way around with the non syntax way of defining queries
oh, dont confuse the
Select
with the query syntax select
its.. different
Select()
is Map()
from other languages
its an A -> B transformationstd::map<T, Y>
?probably. I don't do cpp
what does Select return
Select<T,TResult>()
returns TResult
Ill check its definition
sec
here you go š
right now its
int,int
since thats what I gave it
the select here was only to trigger the console writeline
its not needeok so it takes the Source Type and the Result type
this is equally fine, but no output
and does smth, and then TResult encapusulates, what exactly?
Pobiega
REPL Result: Success
Console Output
Compile: 569.273ms | Execution: 103.021ms | React with ā to remove this embed.
does this make it clearer?
Join surely is an amazing method lol
it can take a query like that
damn
my select function now is
int,string
not really
it takes IEnumerable<T>
yes which queries derive from no?
or IQueryable i guess
sure
but its not relevant really
IEnumerable is just the concept of "you can use foreach on me"
thats literally all it is
ah ye so he
x
is Source and the result that the operation yields
is what it returnsyes
so
TResult
is whatever behind the => yields
C# uses a lot of type inference, so it understands that its int, string here
yes
type deduction is what I call that
return type deduction
type inference is the official term
I'll have to change my terminology anyway, it differs quite a bit
from C++
Generic Methods - C# Programming Guide - C#
Learn about methods declared with type parameters, known as generic methods. See code examples and view additional available resources.
Yeah I read that one, though im not really fond of generic types in C#
its hella limited
i have issues implenting generics according to what im used to
coming from templates in C++, sure :p
but they are actually really powerful
I end up having to rethink my whole approach
yes
and much safer
yeah
less footguns in general
yeah and better compile time errors
š
Okay, so I understand Select() now though
great. Where is just
Filter
and SelectMany
is Bind
seems easy enough, can I add constraints to Select
wdym?
or do I just cast inside Select
if I need a specific type
as TResult
you can do whatever you want for Tresult
you provide the method that maps TSource to TResult
if you want to limit the TSources that might go in, you do that with some filtering method before the select
how does one go about that
Where()?
theres some options
I assume we're talking about you having a list of several concrete types but all sharing some base class/interface?
yes
Like IsDerived from
or smth alike
OfType<T>()
will filter on the concrete type
if you need more control, Where
can also be used
where you just need to return true or false based on the actual itemyeah and filter it there
makes sense
and =>, this piece of syntax sugar
it always yields to a standalone method?
or is it a lambda
under the hood
or does it differ on the context
in which its used
In Select()'s case, a lambda would make sense
however in a class like:
Pobiega
REPL Result: Success
Console Output
Compile: 700.653ms | Execution: 109.636ms | React with ā to remove this embed.
lambda
damn, List has that method built in
no
it doesnt :p
extension method?
yes
same as for array above
fsss i hate those
why?
I'd rather derive from a class, implement it ontop of it
LINQ is almost entirely based on them
and call it a day
lol
ye I guess I need to adapt
extension methods are awesome
because what if the class is sealed?
or you otherwise can't inherit from it
like, it'd be kinda shitty to have to derive every single collection just to add LINQ support
what if a library you want to use wasnt updated and used non-linq types
I mean if they all should be able ot handle OfType just put it in the base clase
mark it virtual and ensure its overrided
though that'd give some overhead I suppose
or have a base impl that suffices for all its derived types
I am not used to using constraints like this either way though
in C++ its not connected to a class to begin with
you just call it independtly and give it both types
thats more a SRP thingy
SRP?
Or just have a static method that pretends to be part of the object?
That's what extensions are
single responsibility principle
ah, didnt know that was the abbrevation
Fair, ill embrace it I promise
just need to get used to it I guess
extension methods can be really powerful yeah
yeah that way you dont always have to rewrite containers
if they lack certain things
hardest part of learning a new language isnt learning the new language, its unlearning the habits from your old language š
Too bad I work in the C++ industry and C# soon
the first time I coded javascript or rust was not pretty
so I need both
thats fine
you dont need to "replace" them, just learn to not force them
ie, dont try to force C# to be C++ and the other way around
its hard when you dove so deep, but im trying haha
i came from the java world so i didnt have to unlearn too much ;p
C# is such a relaxing language comparabily
I like it
its not as verboose and complicated all the time, its refreshing
Uni made you? Because mine sure as hell forced us to use Java...
@Pobiega tysm for your help I'm sure ill bother you again in the future ;)
nah, started out with pascal/delphi back in school, then touched a bit of php and then was looking for some platform independent language for some CLI tools, so ended up with java
thats tough, guess there werent as mny viable options back then
and java was more popular a decade ago, than it is now
yeah that was around 2006-7 iirc
the php -> java transition was also because of a chatbot for a mmorpg i was playing back then which was written in php and i was too sick of duck typing
yw
just make a thread here like you did now š
š
and when you are happy with your answers and want to mark a thread as done,
/close
ituh sorry for the thread drift š
Back then I didnt think about anything programming related
I was a damn child
š
I started coding in 94..
Thats crazy, you two are old and wise huh
my wife would agree with the "old" part
'94 so you write C, ASM?
lol nah
I dont even know what was the language to write
vb6 at first, then PHP, then C# (in 2002)
i started 2000, my older siblings had it delphi in school and i wanted them to teach me
simpler times for programming I assume?
in a way
guess less resources
but less options
yeah, exactly
for me it was harder times, living in the sticks, no internet and the local libraries resources were sparse
no youtube videos that went out of date in half a year after being released...
i still dont like yt tutorials
but it was also slower progress than now. A talented and motivated person can become "fluent" so damn fast these days, given the right resources
yeah
same
I find programming, in a way very tiring nowadays, if I dont keep practicing I lose the ability to write TMP in C++ for instance. So many details, different libs/software/hardware stacked upon eachother
I touched some web dev recently and had to learn 100 different things
oh yeah for sure, if I stopped for a year or so it would be hell to come back into it
and C# is fairly stable, tbh
javascript, you'd have to relearn the entire ecosystem
django, gunicorn, nginx, postgresql, docker, kubernetes, etc
it just keeps stacking
that's good, same with C++ they just add new things but not as fast as compiler support is slow
they add more than the compiler devs can handle, so its all slowed down
web is massive, especially if you include hosting and database like you did there :p
but the complexcity is disgusting, too many things to take into account
good design is crucial
gets tiring
yep, and we didnt even mention the front end
which is framework ontop of framework
unless you want to reinvent the wheel and spend 3 years building a frontend
yeah
web is rough.
I do it for work thou š
but only backend.. and database... and devops..
and its paid much less than some desktop orientated jobs though
eh, not really
for a junior FE, sure
like, my entry salary with a C++ was like
100k
its all supply and demand
all the bootcamps and schools are churning out javascript developers
they are dime a dozen
True, and web dev is filled with people trying to learn it
well thats where most of the demand is
so it makes sense, in a way
that'd balance it though
and make the salaries better
yesn't
I have no idea how accurate this is, but imagine that 80% of dev work today is web
but 90-95% of people who are learning learn for web
so the pool of people looking for entry level web jobs just keeps getting larger and larger
then the demand is low in comparison to its supply
meanwhile, the people who target a lesser used tech, like c++ desktop, sure they have slihtly less jobs to look for, but there are a lot less competition per job
yeah exactly
its relative is what you're trying to say I guess š
so why'd you pick
web dev though
so while web has the highest demand in raw numbers, the relative demand is lower
because I picked 20 years ago
when the numbers were different
how old are you now
37
not that old then
I started with PHP at around.. 14?
12?
bit earlier than me, good age to start
what made you stick around though
It was fun
because I find programming, fun, but it has its
no other reason
well less enjoyable parts
I never imagined it as a career
no?
not until 17-18
like I said, this was back in the 90s
do you still program as a job, or did you take a manager role later into your career?
senior dev/devops engineer
mhm, so you're still fully into it
basically
more or less
not a managerial position at least
and you prefer it like this?
I've been a lead dev and architect before, but enjoyed those roles less
in a way
makes sense
well they can be more burderning I assume
I'm not a people person, but I'm very good with tech
so I try to avoid the peter principle
makes sense
peter principle
is to move up the ladder at some point
to managing positions
Never heard of it
promotion to your degree of incompetence
oh
ie, "you are a good dev, become a lead dev!"
"you are a good lead dev, become a manager"
then you suck as a manager, because they need people skills, not tech skills
yeah some pretty obvious example
though I suppose skills can be learned
even those
for sure
but if you're not happy with it
then you shouldnt adapt
also the process of adapting can be pretty rough and inefficient
I'm swedish, and here a mid-level manager can easily make less money than the devs they manage
I get paid well, so I dont feel like I need to jump to manager for the salaray
thats interesting, that makes sense
its probably a local maximum scenario thou
for me its kind of the same though
mostly because managers in general get paid less than C++ engineers
going via manager to a C level position would definately be a huge pay raise, but its also changing field entirely
and my current company is a startup, so we dont have or need a dedicated CTO
yeah but you wouldnt be able to do that no?
jump to C level
you'd have to start from the bottom or somewhere in the middle
and work your way up progressively over the years
yeah thats what I mean, go manager -> mid level -> top level -> CTO
I mean unless you turn out to be a natural talent surely you wont be put in the highest paying level
exactly
its a huge risk
and if I decided nah, lets go back to dev, im now out of shape
and my CV shows managerial positions
so might be hard to go back
alr, gotta go back to working.
gl hf in C# land
thanks man, gl with work!