tags:

views:

132

answers:

1

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.

+9  A: 

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
You can also put those yield statements directly in the GetEnumerator method.
Steve Dennis
@Steve - Now that is cool.
ChaosPandion
@ChaosPandion - Even if the object is returned how can it be removed ?. Isn't the question also how to remove the object ?
Prashant
@Prashant - I believe the question is simply about implementing IEnumerable. They will clarify if I am incorrect.
ChaosPandion
@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.
ccomet
@ChaosPandian, @ccornet - got it. Also what does OP mean ?
Prashant
@Prashant In this context, "OP" is "original poster". Alternatively "opening poster", but in either case, it refers to the person who asked the question.
ccomet
This is absolutely awesome; I am sorry I forgot to click the "Accept" button. It solved everything for me perfectly.
Stacey