5

I have a class that contains a static number of objects. This class needs to be frequently 'compared' to other classes that will be simple List objects.

public partial class Sheet
{
 public Item X{ get; set; }
 public Item Y{ get; set; }
 public Item Z{ get; set; }
}

the items are obviously not going to be "X" "Y" "Z", those are just generic names for example. The problem is that due to the nature of what needs to be done, a List won't work; even though everything in here is going to be of type Item. It is like a checklist of very specific things that has to be tested against in both code and runtime.

This works all fine and well; it isn't my issue. My issue is iterating it. For instance I want to do the following...

List<Item> UncheckedItems = // Repository Logic Here.

UncheckedItems contains all available items; and the CheckedItems is the Sheet class instance. CheckedItems will contain items that were moved from Unchecked to Checked; however due to the nature of the storage system, items moved to Checked CANNOT be REMOVED from Unchecked. I simply want to iterate through "Checked" and remove anything from the list in Unchecked that is already in "Checked".

So naturally, that would go like this with a normal list.

foreach(Item item in Unchecked)
{
 if( Checked.Contains(item) )
 Unchecked.Remove( item );
}

But since "Sheet" is not a 'List', I cannot do that. So I wanted to implement IEnumerable so that I could. Any suggestions? I've never implemented IEnumerable directly before and I'm pretty confused as to where to begin.

ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
Ciel
  • 17,312
  • 21
  • 104
  • 199

1 Answers1

12

You need to create an iterator that returns the Items that reside in the Sheet.

Using Iterators

public partial class Sheet
{
    public Item X{ get; set; }
    public Item Y{ get; set; }
    public Item Z{ get; set; }

    public IEnumerable<Item> EnumerateItems()
    {
        yield return X;
        yield return Y;
        yield return Z;
        // ...
    }
}

If you don't want to have to call the method you can do this.

public partial class Sheet : IEnumerable<Item>
{
    public Item X{ get; set; }
    public Item Y{ get; set; }
    public Item Z{ get; set; }

    public IEnumerator<Item> GetEnumerator()
    {
        yield return X;
        yield return Y;
        yield return Z;
        // ...
    }

    IEnumerator IEnumerator.GetEnumerator()
    {
        return GetEnumerator();
    }
}
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
  • 1
    You can also put those yield statements directly in the GetEnumerator method. – Steve Dennis May 07 '10 at 15:10
  • @ChaosPandion - Even if the object is returned how can it be removed ?. Isn't the question also how to remove the object ? – Prashant May 07 '10 at 15:23
  • @Prashant - I believe the question is simply about implementing IEnumerable. They will clarify if I am incorrect. – ChaosPandion May 07 '10 at 15:27
  • 1
    @Prashant You can't remove from an IEnumerable in the first place, and the OP is asking about implementing an IEnumerable. The methods the OP would probably need to implement would be a pair of conditional IEnumerables (if X.checked yield return X etc.), which would be lazy loading the necessary "lists" as needed. Then you don't even need to modify the "lists", you just modify the actual items. Which also I think would fit better with the code as the OP describes the situation. – Grace Note May 07 '10 at 15:40
  • @ChaosPandian, @ccornet - got it. Also what does OP mean ? – Prashant May 07 '10 at 16:03
  • @Prashant In this context, "OP" is "original poster". Alternatively "opening poster", but in either case, it refers to the person who asked the question. – Grace Note May 07 '10 at 16:27
  • This is absolutely awesome; I am sorry I forgot to click the "Accept" button. It solved everything for me perfectly. – Ciel May 09 '10 at 19:52
  • I'm trying to implement this code, but in the first statement IEnumerable, Item does not come up in Intellisense and gives me an error. Any Ideas? – CSharper Nov 01 '13 at 14:13
  • @CSharper - Make sure you have this: `using System.Collections.Generic;` – ChaosPandion Nov 01 '13 at 17:16