Enumerables and iterators are a confusing topic for many people even if they aren't new to C#. In this video we'll look at the IEnumerable interface and see how this works with respect to some basic collections. This will serve as a very basic introduction and later on we can expand to more complex topics!
When you're done with this video, you should follow up with this one:
https://youtu.be/fU5-QeSLG2I
You can also follow along in the corresponding blog post here:
https://www.devleader.ca...
View Transcript
So, if you're a beginner in C, then I innumerable and collections can feel a little bit intimidating. And I assume you're here because you clicked this video and wanted to learn a little bit more about that. So, don't worry. We're going to dive into the basics today. And before we do, I'd love to hear in the comments what kind of challenges you've been having with I innumerable so that we could do more follow-up content to make sure that we're addressing some of your concerns. So, in today's video, we're just going to look at some of the basics. We're going to talk about I innumerable, some basic collections and how that works. I'll have example code linked in the description so you can see everything that I'm kind of walking us through today and you can try it on your own. All right, with that said,
let's head over to the code. Great. Okay, so we're here in Visual Studio. I just have a C application. Let me zoom in a touch more. And I'm just going to walk us through what all this says. I've tried to comment it as well so that as I'm talking you can try to read the screen too and see what's coming up. So to start we're going to be looking at an array and an I innumerable and just kind of talk about some of the interactions here. So I've written in the comment you can see right there right at the top these first three lines and just kind of explaining that an I innumerable is an interface that we have access to in C and actually all collections will be implementing this. So I innumerable lets us step over and iterate items in a collection or
a source of data one by one. I'm trying to make that distinction because a little bit later we'll see that it doesn't actually have to be a collection but collections in general will implement this interface. So to prove that we're going to start by declaring an array which you can see on the fifth line here right? So we get five items put into this integer array. And what you'll see on this line eight here, right, I've had a comment as well. So we're going to take the array and ask it to be treated as an I innumerable of ins. You can even see that Visual Studio is saying that we don't even have to do this. It's kind of redundant because implicitly we can assign an array to be an I innumerable. So, I'm just going to leave this in so that it's a little
bit more explicit about what's going on here. And to kind of show you that this is actually the case, what I'm going to do is run this code. I'm going to comment out the rest so we can kind of do it a bit at a time, but I'm going to run this code that actually does a for each loop over the items in the array. It's just going to write the item out to the console. And then I'm going to run the same type of thing, a for each loop on the array that's been cast to an innumerable. So let's go see how that works. Let me go ahead and comment out all of this below and then I will press F5 on my keyboard and run this code. And let me zoom in for us. Right. So we can see using for reach on
the array and it's going to go print out the five items and then using for each reach on the innumerable and we get the same five items and that's because this array is being cast as an innumerable and it's still the exact same collection. I'm going to demonstrate just super quick the fact that it is the same instance. This is important to call out when I did the code that's on line 8. So let me stop this for a moment. When I run this particular line, I am not copying the array. That's really important to note. It's not a copy of the array being assigned into this other variable. All that I have is effectively like a pointer, if you will, that is of type innumerable int. That's just the same reference to my array. So I'm going to demonstrate that. Okay. What I'm going
to do, I'm going to delete this code after, but I just want to demonstrate it in the video, is I can actually say my array, I'm going to modify it after I print it. So, I'm going to change the the first item in the array is actually going to be 1 2 3 instead. So, what we should see when I go run this application, right, we're going to see the numbers 1 2 3 4 5 get printed. Then I'm going to assign 1 2 3 into the array and then do the for each on the innumerable. When I do this, the first element that comes out of the innumerable is going to look like 1 2 3 even though I'm assigning it. You can see on line 17, I'm assigning 1 2 3 into the first position of the array. This is because they are
the exact same reference to the collection. It's just that I have a different variable type pointing at that same reference. So, let's go ahead and press F5 and run that. I will zoom in so you can see it. But you can see 1 2 3 4 5 completely untouched. Then before we print this line, I'm doing this assignment. You can see on line 17 here, it's going to assign 1 2 3 in. And that way when we go print out the innumerable, you can see that even though I modify the first element of the array, the innumerable is still pointing to that same reference collection. That's why we see 1 2 3 get printed there. Okay, so that's some of the basics to start. Let me go ahead and get rid of that. Now the next thing I want to talk about is that when
we're dealing with um innumerabs, we can only iterate over them. So we can only use things like link, which we'll cover in another video, and things like for each loops. We can only step through innumerabs one element of at a time. And I'm going to demonstrate that to you because well we know that we can write for each loops in general. We also know that we can write four loops with integer indexing. So something like this on the array where we're going to go basically iterate from zero up to the length of the array off by one, right? And we're going to print out each item in the array. But we actually can't do that with the innumerable. So, let me go ahead and comment this out. Um, and I have to comment out a little bit more because this code just won't work. Okay.
So, I'll zoom in a little bit more. And you'll see that we don't even have access to the length here. It's just not a property of innumerabs. Now, you might say, well, Nick, you just told us it's the same collection. We actually know the length. It's the same length of the array. You're right. So, let's cheat. Let's do that. Okay, one problem solved. But we still have another problem on line 36. And that is that we cannot use an indexer, which is what you see here. We cannot index into the innumerable. So, the innumerable interface does not have a length or a count. And I should actually demonstrate that as well. There is no count on here. Yes, it's popping up. This is because it's link. It's not exactly what you think. We'll cover that in another video. But we basically have to enumerate the
entire innumerable. That's a mouthful to be able to count what's inside of it. So there is no shortcut to know the length. And then we cannot get an indexer as well. So this code does not work for innumerabs. Um, I can go ahead and run this. You can actually see that it's going to print the the array information, right? So, using for loop on the array 1 2 3 4 5. Remember, I deleted the 1 2 3 part from just a few moments ago. That's why it's not here. Okay, so far so good. We're staying pretty simple. Let's go talk about the next part here. So, I'm going to just zoom out a little so I can read my own screen. And I'm just going to show you that this also works for other collections because one of the first things I mentioned in this
video was that I innumerable is an interface that's implemented by other collections. You can experiment with this yourself uh on more than just list. I'm just going to stop with list here, but let's go basically do this. And you'll see that what I've done is I've made a list instead of an array of integers. I picked different numbers just so that when they print out we can see what's going on. And I'm going to do the exact same thing where I'm assigning the list to an I innumerable of ints. The same thing applies here where I'm not copying the list. I simply have a variable that's referencing the same collection, the same list, except it's going to be of type I innumerable int list int, which just means we have access to even fewer properties and methods. Again, I'll repeat myself, but the exact same
thing applies here where Visual Studio is saying you don't even have to do that. We can directly assign a list into an I innumerable. It will automatically cast for us. So cool. We have that. I'm going to go ahead and run this. And all that this code is doing here is just going to print out the list and then the innumerable version of that list. So let's go ahead and run it. I will zoom in again because the first little bit is really just the stuff that we were looking at before. I've commented out the the for loop. Oh no, it's there. Sorry, it just scrolled off my screen. I lied. But the four each loops for the list down here. You can see lines uh sorry the numbers 6 7 8 9 10 are printed out uh for the for loop. I should change
the wording here. This should say on the list innumerable. So let me go ahead and do that. It'll be a little bit more obvious. Okay. So we've seen that arrays um can be cast to innumerable. Lists can. This is going to mean that dictionaries, cues, stacks, all sorts of other collections that we have access to also can be cast. So the final thing we're going to look at today is just that return types of functions as I innumerable. So let's go ahead and get this commented out and I will explain what's going on here. But I have declared two functions and we're going to use strings just to kind of split things up and make it a little bit more obvious in the console. But I have a function here that return type is I innumerable. But I'm going to pass back a collection that
is an array of strings. So this is the same thing we saw above, right? Where we could cast it. This is automatically so implicitly being converted. I shouldn't use the word convert. It's implicitly being cast to an innumerable of strings. And the same thing here. I'm just showing you with a list. But when we return from here, the caller of these functions can only see it as an I innumerable. So what we're doing is actually reducing someone's ability reducing the caller's ability to access different properties of this collection. We'll talk about this in a future video, why you might want to do this or why there's some value here and then some nuances as well. But all that we're doing here from line 70 to line 80 is we're just going to do four each loops on this stuff again and then print out the
values to the console. So let's go ahead and press F5. I will zoom in for us. And then you can see right at the end here using for each on the array function ABC using for each on the list function ABC. But we can only iterate over these things because like we saw earlier in this video, you cannot use a length. You can count but you have to go through the entire innumerable. It's only a few things in this case. And then you cannot index into the innumerable either. So I'll go ahead and stop that. Now I left a little comment at the end. Why would we want to do this? Like why would we want to write functions that look like this? Are there any implications of doing this? So, we'll have another video to follow up on this and then I'll link it
as well so that you can go right to it. Awesome. So, just a super quick one for today. Just a very highlevel introduction to innumerabs, what it might look like in terms of syntax and how you might be able to kind of start using them in your code. We also talked about the fact that innumerabs are something that you can iterate over, but you cannot get the length of them on a property. You have to actually enumerate the whole set of data to be able to count it. The other thing is that we don't have access to an indexer. In a follow-up video, we're going to look at some of the other interesting properties of innumerabs that we didn't even scratch the surface of in this video. So, if you thought this was interesting, please leave a comment below. I'd love to hear if you
have any other concerns or questions about how you might use innumerabs. And like I said at the beginning of this video, we can follow up with more content about that. So, thanks for watching. If you could do me a favor and like this video if you enjoyed it, subscribe to the channel. It lets me know that you're enjoying this type of content. And of course, if you know other folks that are getting started in C, please share this video with them so they can learn, too. Thanks. And we'll see you next