I have class PlayList like below. I have Playlist instance favorite with song ID {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} I need execute this.
foreach(Song song in favorite.GetSong(4))
{
//Somthing
}
this return me songs with id 1, 2, 3, 4. Next I execute this code.
foreach(Song song in favorite.GetSong(3))
{
//Somthing
}
And I need return song with id 5, 6, 7. But I do not know how to do that. I need remember last returned item and next time start with next item. And if I execute this
foreach(Song song in favorite)
{
//Somthing
}
I want return all song in playlist from last returned item (in this case 7) to end (8, 9 , 10). But this is not necessary.
internal class PlayList : IEnumerable<SongID>
{
private List<SongID> songsInAlbum = new List<SongID>();
public Song this[SongID id]
{
get
{
if (songsInAlbum.Contains(id))
{
return AllSongs[id];
}
throw new KeyNotFoundException();
}
}
public IEnumerable<Song> GetSong(int maxReturn = Int32.MaxValue)
{
int wasReturned = 0;
foreach (SongID id in songsInAlbum)
{
if (wasReturned < maxReturn)
{
yield return AllSong[id];
wasReturned++;
}
}
}
public void AddSong(SongID id)
{
songsInAlbum.Add(id);
}
public IEnumerator<SongID> GetEnumerator()
{
return songsInAlbum.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Thank you for your advices!
It's better not to go against convention here, that will be maintenance nightmare. I'll keep the expected behaviour of
foreach. Instead you can have another overload to enumerate the rest of the songs.I would use
SkipandTakefor this purpose, ie inGetSongmethod, much simpler that way.GetSongis a poor name for a method that returns a sequence. I would rename it toGetSongs, but I prefer a more descriptive name likeGetNextor justNext.To get the remaining songs, another overload makes more sense here. I'm a fan of optional arguments, but in this case I wouldn't want it.
So here we go
Call it like: