C#: IEnumerable, GetEnumerator, a simple, simple example please!
Solution 1
You can simply return the enumerator returned by List<T>.GetEnumerator:
public class AlbumList : IEnumerable<Album>
{
// ...
public IEnumerator<Album> GetEnumerator()
{
return this.albums.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Solution 2
In addition to the other answers if you need a little more control over how the enumerator works or if there is a requirement to customize it beyond what the underlying data structure can provide then you can use the yield
keyword.
public class AlbumList : IEnumerable<Album>
{
public IEnumerator<Album> GetEnumerator()
{
foreach (Album item in internalStorage)
{
// You could use conditional checks or other statements here for a higher
// degree of control regarding what the enumerator returns.
yield return item;
}
}
}
Solution 3
using System.Collections;
using System.Collections.Generic;
public class AlbumList : IEnumerable<Album>
{
private List<Album> Albums = new List<Album>();
public int Count { get { return Albums.Count; } }
public IEnumerator<Album> GetEnumerator()
{
return this.Albums.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
or the simplified version:
public class AlbumList
{
private List<Album> Albums = new List<Album>();
public int Count { get { return Albums.Count; } }
public IEnumerator<Album> GetEnumerator()
{
return this.Albums.GetEnumerator();
}
}
I wouldn't advice leaving out the IEnumerable<T>
interface, because you loose integration with .NET such as possibilities to use LINQ, but you can iterate over the collection using a foreach
in C#.
Or this one is even shorter :-)
public class AlbumList : List<Album>
{
}
Of course this last one is a mutable list, which perhaps is not exactly what you want.
Solution 4
Based on your comment that you want to have a wrapper around a data structure (the list), and an enumerator function to return an Album, I think you're talking about indexer properties, right? This is how you do it:
public class Album
{
public readonly string Artist;
public readonly string Title;
public Album(string artist, string title)
{
Artist = artist;
Title = title;
}
}
public class AlbumList
{
private List<Album> Albums = new List<Album>();
public int Count
{
get { return Albums.Count; }
}
public Album this[int index]
{
get
{
return Albums[index];
}
}
public Album this[string albumName]
{
get
{
return Albums.FirstOrDefault(c => c.Title == albumName);
}
}
public void Add(Album album)
{
Albums.Add(album);
}
public void Remove(Album album)
{
Albums.Remove(album);
}
}
A small console program:
AlbumList albums = new AlbumList();
albums.Add(new Album { Artist = "artist1", Title = "title1" });
albums.Add(new Album { Artist = "artist2", Title = "title2" });
for (int i = 0; i < albums.Count; i++)
{
Console.WriteLine(albums[i].Artist);
Console.WriteLine(albums[i].Title);
}
Console.WriteLine("title for artist1");
Console.WriteLine(albums["artist1"].Title);
Related videos on Youtube
Comments
-
Andrew White almost 2 years
Trying to create an uebersimple class that implements get enumerator, but failing madly due to lack of simple / non-functioning examples out there. All I want to do is create a wrapper around a data structure (in this case a list, but I might need a dictionary later) and add some functions.
public class Album { public readonly string Artist; public readonly string Title; public Album(string artist, string title) { Artist = artist; Title = title; } } public class AlbumList { private List<Album> Albums = new List<Album>; public Count { get { return Albums.Count; } } ..... //Somehow GetEnumerator here to return Album }
Thanks!
-
Andrew White almost 14 yearsHi, Tried the above but got a compiler error on the line IEnumerator IEnumerable.GetEnumerator() "Using the generic type 'System.Collections.Generic.IEnumerator<T>' requires 1 type arguments"?
-
Andrew White almost 14 yearsHi, Tried the first example above but got a compiler error on the line IEnumerator IEnumerable.GetEnumerator() "Using the generic type 'System.Collections.Generic.IEnumerator<T>' requires 1 type arguments"?
-
Steven almost 14 yearsYou are probably missing the line
using System.Collections
on top of your C# file. -
Feidex almost 14 years@Andrew White: IEnumerable/IEnumerator without generic type parameters is in the System.Collections namespace.
-
HOKBONG about 10 years+1 I like the additional point you brought up on more granular control of the list being returned. Thanks.
-
ouflak about 10 yearsThis helped me turn about ten lines of code into just one line of code.