Monster shadow

VIDEO

C# IEnumerable: Loop me harder - [5 Rider licenses to give away]

Description:
IEnumerable and IEnumerator play an integral part in your day-to-day development, whether you know about them or not!
ADD A COMMENT

Kathleen Bryan
Your Unity/C# content is literally awesome. Thank you for your videos and the work you put into this!
Tarodev
Thank you Kathleen 😊
SFP
the awesome thing about your tutorials is that you are clearly experienced in what you show. love it, subbed with da bell 👍
Udi Beres
Rider <3
Novaxy
I love your content and I'm just starting to code, but why "Loop me harder". Why.
Tarodev
Because it's ridiculous. Glad you're enjoying the content man!
Erik Skyler
Man as a developer how are you looking at your keyboard so much? You should be looking at the screen 90% of the time to be efficient. Think of all the wasted time and eye movements from not knowing how to type without looking.
Tarodev
@Erik Skyler text sometimes does not convey the message accurately. Truth be told though, although I don't type slow (70-80 wpm), I do look at the keyboard when I do a few actions. Improving that would certainly be a boon. I missed all the touch typing classes in school so I kind of just butcher my way through it 😢
Erik Skyler
@Tarodev Hey man I'm just trying to help you out by pointing out a deficiency. I'm not trying to bring you down, I just see a big opportunity for improvement.
Tarodev
My mic is in between me and the keyboard when I record. Makes it difficult as I'm positioned differently. Feels like a weird thing to defend myself against. Although the comment is probably the weird thing.
Alex Mokbel
I'd love a license for visual studio. Recently subscribed to you through your grid system. The video is good but honestly still trying to wrap my head around things. I don't understand memory allocation vs cpu time concepts at all. So i guess thats limiting my understanding of the video. As for what i'd like to see.... hmm, well, maybe random map generation that can be hooked into your A star algoirethem video and grid movement videa that you made? I want to make a 2d rpg that uses grid system with random map generation :)
Alex Mokbel
@Tarodev Haha! I knew it! :P
Tarodev
@Alex Mokbel Sir, I don't know what that means, are you a crazy person?
Alex Mokbel
@Tarodev bubble-trumps
Alex Mokbel
@Tarodev Hello Matt, I sent you an email from my own email. I used the email you provided on your youtube page for "business" contacts. I didn't want to leave the email address here for spam and privacy reasons :)
Tarodev
Give me your best contact email (possibly make it a junk email)
Hardik Nadiyapara
we would like to see trie algorithm in c# for word search
Hoàng Nguyễn
I have commented on your channel afew months ago to learn, now I got my games in 2D &3D running, thank you for sharing ☺
Tarodev
I love to hear it!
Anass
Hey, thanks for the wonderful video and very useful information,a lot of developers do not understand well the meaning of the IEnumerable and this may lead to many Performance issues. I would like more videos about Rider and or resharper and how you are using them to refactor existing code? I would definitely enjoy following these videos. Cheers
Divain'sYoutube
Great content! Thanks for sharing! As for someone whom sometimes watching on a phone, I'd love to recommend to make your text bigger so it'll be easier to see. Keep it up :)
YulRun
How are you liking Rider vs something like VSCode?
Tarodev
It's very good. I dislike vs code for anything c#, but I do use it for typescript, python and rust
Rajakumaran Chakaravarthy
didn't know about the multiple enumeration. thank you. I would love to see a video about C# lowering concept also would love to get a key 😃
Bunggo99
your vids are the best, it's hard to find intermediate/advanced content these times. I would like to see some vids about 2D random procedural generation (like terraria), please.
Paritosh Vaidya
we love have a video on a game design pattern , that to make modular ,optimize code for the game
Dave
Interesting video, maybe next time you tell something about IDispose? What’s does, how to implement etc. This interface is often used by developers without knowledge what’s doing.
Richard Tongeman
Thanks for another great video! I'd like to see a video about controlling shaders with scripts and GPU instancing. I would love to use rider my license just ran out!
Nirast 25
Great breakdown of how IEnumerable/IEnumerator works, wish we had something like this in Uni. I'd love to see how the Unity renderer works, mainly for 2D sprites.
Tim Gardhouse
Great choice of examples here. The gotchas are a good thing know! I'd like to be in the running for a copy of Rider. I've used up my free trial and it was just a different world of programming. Future video ideas: More areas of C# that are a bit more intermediate/advanced, with potential gotchas. More of your preferences for Unity tools you find essential (like DoTween - that video led me to your channel). I'll also second the broader architecture/structure idea.
Skylor Beck
Dude! I'm so jealous! Gratz on the sponser. I love Idea and I wish I could use Rider. My plan was actually to try to grow on YouTube until I can get into the partner program with them. I'd love to get a license but I'm damn cheap. I actually just put out a video of my own, where I shouted you out for the Async/Await video. BTW I am blown away you only have just under 9k subs.
roytazz
A video about events and delegates would be a good addition to your C# series
Tarodev
You're incredibly correct on that assessment.
SEE ALL COMMENTS


Transcript:

hello and welcome today i'm going to be talking about enumerables and
enumerators now this can be a complex topic and unless you know how it's
working underneath your code might not be doing exactly what you think it's
doing so i'm going to show you uh what they are how to use them and actually
how to make your own uh enumerables so let's start by making a class and let's
just call this uh hero academy and in here we're going to have a
name of the academy and let's call this uh
olympus olympus i've been playing a lot of hades
recently private list and let's make this
a string list and this will be uh olympians
and this will be equal to a new list and this will have who are the best
olympians zeus was about us uh
poseidon was possible and we'll do
afrodity or is it aphrodite i don't know cool so over here we'll say academy
equals new hero academy and just as a normal object we can you
know see the name there we obviously can't see these olympians
as it's a private list but let's say we wanted to uh
loop over this object so we wanted to say 4h bar
name in
academy obviously this is not going to work
because it's saying hero academy cannot use 4-h because it doesn't implement
high innumerable so let's fix that over on our hero academy let's make this
implement i enumerable and that will be in the system
collections namespace so this is just telling c sharp hey this hero academy
can be enumerated somehow it doesn't know how to enumerate
it but we'll get to that so this is giving
us an error it's saying hey we need to implement the missing members
so we'll see there's two words here i
innumerable and i in numerator obviously seems very similar so this one
tells c sharp it can be enumerated this one tells c sharp how to enumerate
it all right so ienumerator is another interface and if
we just go into it and these are the three functions
required uh to uh use 4h properly all right so it's saying uh move next so
move to the next index uh what the current item of the array is so that
would be this here and if we ever want to reset it go back
to the very first index of the array uh we can do that too
so let's head back so
we could fill out all those methods ourself right we could make our own uh
enumerator which we will do later on but for now let's cheat we know that we just
want to iterate over this list here and we know
that list if we go into it we go down into i list
we know that list already implements i enumerable all right or else we wouldn't
be able to actually use a 4-h on a list so because we know we're iterating this
let's just return the olympians
dot get a numerator right because we know that our list implements enumerable
which means we know that it's got this function so we're just going to return
back out to the 4-h loop the lists
enumerable so now we can say console.writeline
name so
take note this is an object that we've just created but now we can iterate over
it as well as get access to the normal properties on the object so if we press
play here we'll see zeus poseidon aphrodite okay
cool so now you know what these two things are
and roughly what they do i'm going to now
just stop on this example and i'm going to show you how you're probably already
using ienumerables and how you could potentially be screwing up uh what you
think you might actually be doing i'll show you a few gotchas
so i'm going to create a rand instance here a random instance as i know that
i'm going to be using random a few a few times
and then i'm going to create a list of numbers and i'm just going to do this by
enumerable range 0 to 10 and i'm going to list it so basically
what this is doing is it's just creating a list of numbers from 0 to 10.
so now let's say we want to query some of these numbers and an easy way to do
that is with link so let's say random numbers
and we'll go numbers here and then we'll order them by number and then we'll use
our rand next so we're just like randomly ordering these numbers and
we're just going to take three of them so now we could simply for each var
number in random numbers and we could say
console.writeline number
so let's press play and we'll say three random numbers seven
one zero but
what do you think is going to happen if we copy this for each loop and do this
twice right so let's press play
zero four one one six zero so this is this is actually
giving us two sets of random numbers you may have looked at this and thought okay
here are the random numbers right these are the random numbers that we've just
returned from this query and now we're just going to loop over them two times
but that's not the case so if we inspect what type this is we will say that it is
a type i.enumerable okay so this is not storing the numbers this is
not a variable with three numbers in it this is just a query and then when we
get here we're running this query right and then once this for each loop
finishes and it goes to this one we are then running the query again to uh get
another set of random numbers if you're just learning this now you're probably
thinking oh i need to go back through some of my code
and find out if i'm actually performing enumerations multiple times now that
doesn't mean that performing an enumeration multiple times is a bad
thing okay sometimes it can be a very good thing but you need to just know
that this is how it works now if you wanted to
loop these number like the same set of numbers two times you could simply do
this to list so now we're saying grab the numbers order them take three
of them and then set them in stone make a list out of them actually
cement them in this variable so now this variable is of type list right so now if
we press play we will see 537 537 so now that's more
predictable right so there's a few things you need to keep in mind here one
two listing means you're grabbing all of the items and you're putting them all in
memory in the heap right you're grabbing them or putting them all in memory which
means once this goes out of scope the garbage collector is gonna have a
little bit of extra uh allocated garbage that's gonna have to
clean up whereas if you don't to list it
we are actually only pulling one number at a time uh into the scope right now
we're pulling one number into memory at a time which can obviously be a good or
a bad thing for example say you have you've got uh
you're gonna grab a million items right if you to list it you are putting one
million items into a list and that could crash your app right it could it could
absolutely crash your app uh and that in that scenario it might be better to
leave it as an enumerable even if you're going to do it
two times right because not not every query is going to
return uh random results right this could you could just do a where
statement here and you could iterate over them one at a time and then later
on in your uh in your function you could also iterate them over again and it may
not matter that you're doing the where statement two times uh the benefit is
better the cpu cycles is better doing the where statement twice than uh
pulling them all into memory right so just a uh direct example right let's
let's say this is not random numbers let's just rename this and uh call it uh
grid positions right so let's say that we're this is actually doing some kind
of path finding and just pretend for a moment because they're not actually grid
positions they're numbers but uh let's say instead of uh doing something random
we're doing where and just to make this simulate a more
expensive task like pathfinding for example let's just say we're uh delaying
for 10 milliseconds and we'll wait for that
and then we'll return true so i know this is a very pointless uh
where statement i'm literally just returning true on everything but
this will allow us to simulate a longer running task
um and let's
not just take three let's grab them all so then if we do this
let's say four times right and this is disgusting so that's
actually iterations equals four
and then here we can do four each uh four iterations
then we can just slap that in there and it's not so chunky
cool so basically we're just doing we're looping that for the iterations but
we're we're calling our enumeration four times now right
and just to inspect this let's do uh a watch equals new stopwatch
and we'll say watch dot oops watch dot start and then down here we'll do watch
dot stop and then we'll do console right line
elapsed watch dot elapsed milliseconds
cool so we're now going to call this enumeration
four times so if we press play here you can see how that slowly went down
like that could be a pathfinding algorithm or it could be something even
more expensive right you could be um you could be reading from disk or
something so that took 600 milliseconds to loop
this four times uh because we're actually redoing this
pathfinding algorithm four times so instead of doing that we could to list
it right and pull them all into memory just
process it once pull them all into memory
and now when we press play here it's like almost instant right nine
milliseconds so from nine milliseconds all the way up to 600 milliseconds is
the difference between two listening or not so it's it's really it's a judgment
call do you want to allocate the extra memory of the two list right
uh and just remember you're not just pulling all the items into memory you're
also creating the the class itself right so that's also allocated uh which will
have to be garbage collected sorry it's it you've got to weigh the pros and cons
do you want to list it and allocate the memory or do you want to actually just
keep running the uh enumerable over and over okay so you need to probably
benchmark in what situation is best okay if it's a really quick uh if it's a
really quick statement like like a simple wear statement or an order buyer
that doesn't obviously have this stupid weight here it may be perfectly fine for
you to just double enumerate instead of pulling into a list so yeah if you have
just learned this i'm sure you are thinking about some code that you've
written that you probably need to go back and
refactor or at least take a look at to see if you're doing the right thing or
if you're running multiple enumerations when you shouldn't when you shouldn't be
uh or maybe multiple enumerations is fine you never know
and just a little side note uh if we remove this to list so it's an
innumerable again writer i've only just started using
writer over the last two weeks but uh writer gives you little performance
optimization tips like it's doing right here possible multiple and an
enumeration right it's it's telling us hey
you may not be realizing that you're actually enumerating this multiple times
i'm going to warn you about it maybe you want to do something about it maybe you
don't but it's it's small things like that
that just make writer such a nice ide to use
as well as obviously all the audio complete and just other suggestions it's
just fantastic and before when i used to use a visual studio i also used to use
resharper plugged into it which is also made by these guys
and whenever i used to turn off resharper and just use basic visual
studio my development speed just went way down
resharper and writer just do so much for you that you don't even realize how much
they're doing until you actually turn it off so i highly recommend
the writer idea it's fantastic or getting resharper for visual studio
honestly you won't look back uh it's fantastic anyway that's a side
note hello so i'm happy to say that this
video is sponsored by jetbrains the creator of resharper writer and a bunch
of other beautiful tech they were lovely enough to give me five
one year licenses to the writer ide which i'm using in this video all i'd
like you to do to get your little fingers on it is comment down below what
you think of this video and give me an idea of what you would like to see in a
future video and also let me know that you would indeed like one of these
licenses and in the near future i'll pick five of you and i'll send you a
license and that's about it enjoy the rest of the video bye
okay so now that you kind of know what the enumerations are doing i'm going to
show you it uh actually a deep dive into it i'm going
to write my own iron numerable and this will be a type int let's say get numbers
and in here i'll do a for loop for 10 and
now as you as you saw here we're pulling one item into the scope at
at any one time right we're not grabbing them all we're just pulling one at a
time and we can do that with iron numerables like this with the contextual
yield keyword right so we're yield return and we'll just return i and if
you're if you use unity you may actually recognize this yield as uh in co
routines you will say yield new weight for seconds right or wait for the end of
frame okay so instead of waiting for the end of frame we're just uh waiting for i
to be returned so now down here we can say forage va
num in get numbers and we'll just console write line the
num and if we set a breakpoint here and here
right and let's actually also console rightline and we'll say
uh processed
i and let's press debug so it's come down here it said alright
get first get get numbers so now it's asking for our first number which will
be zero obviously and then once once we uh go to the next
step here it's now down back into our for each loop right and this number is
now zero so we'll console log our number and now it's going to come back up here
and ask for our next number so now i will be equal to 1 and it's going to now
return that and it's just going to keep going
through this pulling each item one by one right as soon as this number here
goes out of scope it's now it's it's now going to be triggered by the garbage
collector at some point in the future to say clean it up we don't need it anymore
right and now this next number is now coming into scope one by one
uh so you can see uh just how powerful this could possibly
be right so we could actually we could actually say that this is going to
return one million numbers okay but we could do something like this now but if
num is more than five then uh break out of this loop
right and we can do just something down here just to say hey
uh right line we're done
so even though that this innumerable could potentially return one million
numbers because here we're breaking out of this statement to say if we're five
we're done and we're leaving this will only process
five or six sorry more than five so instead
if you had a get numbers function right and it was a list right and you're
saying new list here add to list and then return the list even if you're only
wanting five on the outside this will still do one million numbers and then uh
you will just end up using five right so plus that's pulling a million numbers
into memory uh for you to only use five right so i
always recommend if you've got some kind of function that returns a collection
return an ienumerable yield it if you can
and that way in one point of your application you might use the full
million whereas in another application or another part of your application you
you have the luxury of only using the five
and we can actually use link on this so uh three numbers
and we'll say get numbers dot take three
and if you remember this is actually an innumerable as we're using link here
sorry this is not storing the numbers once it gets down to here this still
hasn't even executed this this function hasn't even called yet it will only
actually call if we act on something and a super interesting part is if we
console right line and we'll do like three numbers
and we'll just say first right
even though that we're saying that we want to take three here because we're
only acting on the first one and we press play
only the first one it's only going to iterate this one time just to grab the
one that we need and then just like
just ignore the rest it's not even going to do anything for the rest so
you can write super performant code by using innumerables and you can reuse a
lot of your code by having one function to return a ton of different uh
amount of items okay instead of returning the list and grabbing all of
them and then just taking some of the list
so keep that in mind because it's a very good performance tip and a good code
reusability tip now that we have uh kind of explored this a little bit i
will just show you lastly how you can actually create your own
iron numerator so right now we were lazy we just returned the list iron numerator
right because we knew that this one already had it
but let's create our own so let's create a class this will be an academy
uh innumerator
and this will implement ie numera iu numerator okay and as i
showed you before this has three functions that we need to implement move
next reset and current object we know that we're gonna need to return this
academy enumerator here right instead of like just grabbing the list one so we
actually need to know what we're enumerating okay we know that we're
going to be enumerating this list so let's create a constructor here
and in this constructor it's going to take a list of type string and this will
be the names and then down here we'll say names
equals names and then we will auto scaffold that
and then we also need a index because we need to know which item
of the array we need to keep handing to them so let's go private inch
index and this will be equal to negative one
and the reason i make it negative one is because
do i have my no i don't ba academy whoops academy people's new
hero academy then if we do 4h by hero in academy
so when we first hit this
it's going to immediately say get next move next right so if we made
this zero it's actually going to make it one so then we're going to grab the
second element of the array so you need to set it to negative one so that when
you first say it it's going to be on on index zero this function here is
actually going to do two things one it's going to iterate the index
okay so move to the next index and two it needs to return a boolean and this
boolean is saying is there another item in the array uh if this returns false
it's going to get to here after iterating it a few times it will get to
here it's going to return false so then it's going to just leave the forage loop
and then continue execution down the rest of your application
so we can easily say is there another item by saying
is index less than our names.count
if it is then yes true keep keep iterating
um our reset function is very easy it's just index is going to be equal back to
the start of the uh of the array so that we can enumerate it again so if you
remember on our numbers array we were enumerating and then we would have
another 4-h loop enumerating again so that's because the index would be reset
to negative 1 each time and then our current is just uh the
current version of our um of our object so that will be this here
this is our current version of the iteration
so here we can just say uh return uh names
index and resharper is actually telling us
that we can make it an expression body so that's nice and neat
so now we've got our custom academy and numerator
so here instead of returning the list one directly we can
oh sorry doggies all over the place we can return our custom academy and
numerator new academy enumerator and we've got a uh constructor here which
takes in the name so let's send in our olympians and now here we can say
console.writeline hero so now that this is going to be using
our brand spanking new academy enumerator
so let's just check to see if that works beautiful
and if we put our mouse over this we'll see that this is actually a type of
object okay it doesn't actually even know that this is uh we're
enumerating strings here which means we can't actually perform link expressions
here we can't do this for example we can't say where
so to enable link expressions and to add
proper typing to this we just need to change these to the generic types so
instead of just i innumerable we'll have an eye interval of type string
and this is saying hey you
have got more methods that you need to implement and if we go into the generic
version of this we'll see that there's the generic get enumerator right
but then this generic uh eye innumerable is actually inheriting
from the base iron numerable which also has like the basic get a
numerator so that falls back onto us to have to
actually implement both so let's remove this
and then just implement those two [Music]
so the good thing about this is we don't actually have to worry about this base
one okay so this base one they've already pre-filled it to say hey just
return whatever the generic version uh returns so we call in the base one by
actually directly referencing the the interface
and then calling the method directly so we can just ignore this one and just use
this one to return our customer numerator so we'll return new academy
and numerator and we'll send in our olympians
and this is giving an error it's because our enumerator is actually also needs to
be generic so let's make this a string and the generic version of iron
numerator requires a little bit of different setup so i'm just going to
remove this it needs a disposable which we won't actually use
so i'm just going to remove the not implemented throw
and uh re-implement the get so this is just still going to
be names and then index and we'll make this the expression buddy
cool and if we press play now
we'll see that it returns our two names which are long enough
cool bananas so uh ultimately you don't need to
know this side like how to make your own
innumerable how to make your own enumerator
this is advanced stuff right but this stuff that i have taught over here i
wish i didn't actually remove it all but yeah so this stuff
knowing when to list your
innumerables is vital okay you might have to go through your old code to
check to see if you're actually enumerating things multiple times when
you shouldn't be but
this stuff is important so make sure you study this and know what you're doing uh
it could save you know database rights or
file system rights or pathfinding a million times and you shouldn't be happy
when you shouldn't need to so that's it that's all i wanted to show
you if you enjoyed the video subscribe let me know down below what other
advanced topics you would like me to cover uh i've got a list but uh it's
always good to have it keep growing so that i can just smash through them and
uh that's it i'll see you in the next video bye
you