I tried to do something like this but this doesn't work:
class Garage
{
private List<Car> cars = new List<Car>();
public Car this[int i]
{
get { return cars[i]; }
}
//...
}
Garage g = new Garage();
//get CS1579 - no GetEnumerator definition
foreach (Car c in g)
{
//...
}
As MSDN says indexers can be overloaded, so I decided to ask experts here. How to overload indexers to cooperate with foreach
loop?
foreach
has nothing to do with indexers. You need to declare a GetEnumerator
method that returns an enumerator for the collection. (While you’re at it, it may be wise to implement the IEnumerable<Car>
interface as well, which provides this method.) In your particular case, you can do it easily like this:
class Garage : IEnumerable<Car>
{
private List<Car> cars = new List<Car>();
public Car this[int i]
{
get { return cars[i]; }
}
// For IEnumerable<Car>
public IEnumerator<Car> GetEnumerator() { return cars.GetEnumerator(); }
// For IEnumerable
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
A huge benefit of implementing the IEnumerable<Car>
interface is that you can use all the LINQ extension methods, e.g. Where
and Select
, for example:
var redCars = myGarage.Where(car => car.Color == CarColor.Red);
You can also make your cars private, and add a public or internal property, because tomorrow in your garage you will have Employees and Tools and so on, so your enumerate will make no sens. So with the followings you have no more code to provide :
private List<Car> m_Cars=new List<Car>();
private List<Employee> m_Employees=new List<Employee>();
public List<Car> Cars { get { return m_Cars; } }
internal List<Employee> Employees { get { return m_Employees; } }
So you can use foreach, on cars, employees like this:
var redCars = myGarage.Cars.Where(car => car.Color == CarColor.Red);
var Employees1 = myGarage.Employees.Where(e => e.Name == 'xxx');
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