Индекс перегрузки имеет класс foreach'able - PullRequest
10 голосов
/ 22 сентября 2010

Я пытался сделать что-то подобное, но это не сработало:

    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)
       {
           //...
       }

Поскольку MSDN говорит, что индексаторы могут быть перегружены, я решил обратиться к экспертам здесь.Как перегрузить индексаторы для взаимодействия с foreach loop?

Ответы [ 2 ]

36 голосов
/ 22 сентября 2010

foreach не имеет ничего общего с индексаторами .Вам необходимо объявить метод GetEnumerator, который возвращает перечислитель для коллекции.(Пока вы занимаетесь этим, может быть целесообразно также реализовать интерфейс IEnumerable<Car>, который обеспечивает этот метод.) В вашем конкретном случае вы можете легко сделать это следующим образом:

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(); }
}

Огромным преимуществом реализации интерфейса IEnumerable<Car> является то, что вы можете использовать все методы расширения LINQ, например, Where и Select, например:

var redCars = myGarage.Where(car => car.Color == CarColor.Red);
0 голосов
/ 21 ноября 2016

Вы также можете сделать свои машины частными и добавить общедоступную или внутреннюю собственность, потому что завтра в вашем гараже у вас будут сотрудники и инструменты, и так далее, поэтому ваше перечисление не будет иметь смысла.Таким образом, со следующим у вас больше нет кода, чтобы предоставить:

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; } }

Таким образом, вы можете использовать foreach на автомобилях таких сотрудников:

var redCars = myGarage.Cars.Where(car => car.Color == CarColor.Red);
var Employees1 = myGarage.Employees.Where(e => e.Name == 'xxx');
...