In many of our projects I have seen a few custom collection / or container classes that hold a some sort of generic collection, e.g. a List(of T)
class.
They usually have a GetXXX method that returns a IEnumerable of whatever type the custom collection class uses so the internal collection can be iterated around using a foreach loop.
e.g.
public IEnumerable<UploadState> GetStates
{
get
{
return new List<UploadState>(m_states);
}
}
My question is that should these classes instead implement the IEnumerable
interface, and call GetEnumerator
on the List itself.
Is there a preferred way, or is it up to the developer?
If your class is a custom collection class then yes, it should implement IEnumerable<T>
. In this case a public property for the inner list would be redundant. Imagine a simple class:
public class People : IEnumerable<Person>
{
List<Person> persons = new List<Person>();
public IEnumerator<Person> GetEnumerator()
{
return persons.GetEnumerator();
}
}
But if your class cannot act like a collection then provide a public IEnumerable
property for its elements:
public class Flight
{
List<Person> passengers = new List<Person>();
public IEnumerable<Person> Passengers
{
get { return passengers; }
}
}
Anyway, it's always up to the developer to choose the right design.
I would do it that way:
public IEnumerable<UploadState> GetStates
{
get
{
foreach (var state in m_states) {
yield return state;
}
}
}
It is cleaner, your users don't get a list where they shouldn't (they could cast it to a List<T>
after all) and you don't need to create a List<T>
object.
EDIT: Misunderstood the question. I think if the class is meant to be a collection, it should implement IEnumerable<T>
.
Consider that in your code example a new list created. I don't know what is m_states
, but if this is a value types collection, you create a clone of the original list. In this way the returning list can be manipulated form the caller Add/Remove/Update elements. without affectiing original data.
If m_states
are reference types, this still creates a new list which can be again manipulated by the caller Add/Remove/ No update elements (it's a reference!) without affecting original data.
What about IEnumerable<T>
, its just a way to make a returning type generic, and not make strong coupling to List<T>
type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With