user159603
user159603

Reputation: 95

Calling IEnumerator from an Interface class

I am new to enumerating collections so forgive if this question sounds silly.

I have an class

public class PersonStuff : IPersonStuff, IEnumerable<User>
    {
        Person person = new Person();
        ...

        IEnumerator<Person> IEnumerable<Person>.GetEnumerator()
        {
            return (person as IEnumerable<Person>).GetEnumerator();
        }
}

As you can see, I am implementing two interfaces in the above: one being IPersonStuff and the other being IEnumerable.

The Person class is a simple getter/setter each type being of string e.g. name, address except dateofbirth which is DateTime.

And in my IPersonStuff I have this:

interface IPersonStuff
    {
        ...
        IEnumerator<Person>  IEnumerable<Person>.GetEnumerator();
    }

Once working, I would like to call it in the following manner (from any class):

    IPersonStuff personStuff = new PersonStuff();

    foreach (Person u in personStuff)
    {
        //this loop should iterate thru the elements.
    }

However, I get the following error:

Basically I want to know how is it possible to call the IEnumerator IEnumerable.GetEnumerator() I have in the PersonStuff class through the IPersonStuff Interface.

Upvotes: 0

Views: 974

Answers (2)

Jeffrey Hantin
Jeffrey Hantin

Reputation: 36534

Is IPersonStuff itself collection-like, or just a bunch of properties? If it's not collection-like, there's no need to make it enumerable.

I believe the error is due to using System.Collections.Generic but not System.Collections -- the non-generic IEnumerable is thus not in scope.

I think that if you want IPersonStuff to be enumerable then you can just have IPersonStuff inherit IEnumerable<T> (which in turn inherits IEnumerable). Otherwise, I don't think you'll be able to use foreach over a reference to IPersonStuff.

EDIT Based on further comments and edits, it looks like PersonStuff is intended to be a collection-like data access class for Person, with instantiation managed in monostate fashion.

The monostate instantiation defeats the point of defining an interface IPersonStuff: if you always create it with new PersonStuff() in-line, then (bar bytecode postprocessing) there is no opportunity to use some non-default implementation of the interface.

I would suggest defining some sort of data access context object with properties representing each of your global entity collections, then pass that around in your choice of fashion -- using a parameter or accessor-based singleton is preferable to a monostate. This object may then wrap a database connection, NHibernate session, or similar.

Upvotes: 5

Fung
Fung

Reputation: 7790

You're getting the error most probably because like what Jeffrey said you're missing a reference to System.Collections.Generic which has the non-generic IEnumerable. Once you have the correct reference you won't need the cast of (person as IEnumerable).

On whether it should/can be type safe depends on your situation. If all elements of what you're enumerating through are of the same type (i.e. fixed class, interface or subclass) that you should/can use the type safe IEnumerable. But if say maybe you want to enumerate all the properties in Person (which sounds like what you might be attempting) and you're returning diff types then you'll have to use the non-generic IEnumerable.

If you are enumerating through the properties of your class then one nice trick is to use yield return for each property (instead of writing a custom class that implements IEnumerator) in Person.GetEnumerator();

Upvotes: 0

Related Questions