C#: IEnumerable, GetEnumerator, a simple, simple example please!

51,360

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);
Share:
51,360

Related videos on Youtube

Andrew White
Author by

Andrew White

Programming for kicks

Updated on July 09, 2022

Comments

  • Andrew White
    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
    Andrew White almost 14 years
    Hi, 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
    Andrew White almost 14 years
    Hi, 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
    Steven almost 14 years
    You are probably missing the line using System.Collections on top of your C# file.
  • Feidex
    Feidex almost 14 years
    @Andrew White: IEnumerable/IEnumerator without generic type parameters is in the System.Collections namespace.
  • HOKBONG
    HOKBONG about 10 years
    +1 I like the additional point you brought up on more granular control of the list being returned. Thanks.
  • ouflak
    ouflak about 10 years
    This helped me turn about ten lines of code into just one line of code.