Ok, so here's the basic code:
class foo
{
String name;
int property;
}
class bar
{
private List<foo> a;
private List<foo> b;
}
I'd like to make it so that calling code can iterate over either list but I want to keep them protected from editing. I've looked into implementing the IEnumarable interface but the problem is that it expects a single "GetEnumerable" definition, but I want two different enumerators. For instance, i want to be able to say
foreach(foo in bar.getA())
{ //do stuff }
and then
foreach(foo in bar.getB())
{ //do stuff }
Do I have to subclass each element and implement the IEnumerable interface over each, and then include THOSE as properties? Am I misunderstanding the IEnumerable interface? I know that the List class has it's own Enumerator, so I could do something like
class bar
{
private List<foo> a;
private List<foo> b;
public IEnumerator<foo> getAEnumerator()
{ return a.GetEnumerator();
public IEnumerator<foo> getBEnumerator()
{ return b.GetEnumerator();
}
but then my for loops look like this:
bar x = new bar();
IEnumerator<foo> y = x.getAEnumerator();
while (y.moveNext())
{
foo z = y.Current;
}
so I lose the readability of "foreach".
Is there a way to accomplish using "foreach" over these lists without exposing these lists publicly? I'm still trying to get my head around the IENumerable interface, so maybe I'm missing something obvious.
Don't expose a
List<T>
, expose something else, like anIReadOnlyList<T>
instead:Any changes to
a
andb
will reflect inA
andB
.Also note that while you can cast a
List<T>
to anIReadOnlyList<T>
, the calling code can cast it back toList<T>
. The above method returns aReadOnlyCollection<T>
which provides a safeguard against casting back to a mutable collection type.The
readonly
keyword only ensures you don't substitute references toa
andb
with something else later on.