Реализация интерфейса GetEnumerator

У меня есть этот цикл foreach, в котором я пытаюсь просмотреть список documentTables класса Table, который содержит объекты Table, которые содержат объекты класса Row. В настоящее время я получаю сообщение об ошибке: оператор foreach не может работать с переменными типа test1.Table, поскольку он не содержит общедоступного определения для GetEnumerator. Я не совсем понимаю, что происходит, и не уверен, как лучше всего реализовать интерфейс.

for (int i = 0; i < documentTables.Count(); i++)
{
   foreach (Row r in documentTables[i])
   { 
      // some functionality here
   } 
}

TABLE CLASS (класс Row почти такой же, имеет несколько строк и конструктор):

class Table { 
public Row a; 
public Row b; 
public Row c;

public Table (Row _a,Row _b,Row _c)
 {
a=_a; 
b=_b; 
c=_c;

} 
}

person AJL    schedule 05.10.2017    source источник
comment
Если вам нужна строка, вы выполняете цикл по строкам, а не по таблицам: documentTables[i].Rows;   -  person Steve    schedule 05.10.2017
comment
Вы должны показать свой класс Table, реализует ли он IEnumerable<Row> или просто содержит коллекцию, в которой хранятся строки? В этом случае используйте это свойство, например: foreach (Row r in documentTables[i].Rows)   -  person Tim Schmelter    schedule 05.10.2017
comment
У вас есть реализация таблицы и строки, без которой трудно догадаться   -  person duongthaiha    schedule 05.10.2017
comment
Покажите, как реализован Table.   -  person Sweeper    schedule 05.10.2017
comment
Класс @Sweeper Table имеет только переменные строки и конструктор   -  person AJL    schedule 05.10.2017
comment
Итак, ваш класс Table не может иметь более 3 строк? Я действительно предлагаю вам вместо этого использовать свойство List<Row>. Но зачем вы изобретаете велосипед? Чего не хватает в классе DataTable, предоставленном Framework, который вам нужен для создания собственного класса Table?   -  person Steve    schedule 05.10.2017


Ответы (1)


https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in

Оператор foreach повторяет группу встроенных операторов для каждого элемента массива или коллекции объектов, реализующих IEnumerable или интерфейс IEnumerable.

Итак, ваш класс Table должен реализовать IEnumerable:

class Table: IEnumerable
{
    public Row a;
    public Row b;
    public Row c;

    public Table(Row _a, Row _b, Row _c)
    {
        a = _a;
        b = _b;
        c = _c;

    }

    public IEnumerator GetEnumerator()
    {
        yield return a;
        yield return b;
        yield return c;
    }
}


public class Row { }

Затем вы можете сделать:

var myTable = new Table(new Row(), new Row(), new Row());
foreach (var row in myTable)
{
    // some functionality here
}

Другая возможная реализация вашего класса Table (я думаю, более гибкая) выглядит следующим образом:

class Table: IEnumerable
{
    private Row[] _rows;

    public Table(params Row[] rows)
    {
        this._rows = rows;

    }

    public IEnumerator GetEnumerator()
    {
        foreach (var row in _rows)
        {
            yield return row;
        }
    }
}

Теперь количество строк в конструкторе не ограничено тремя.

person Pedro Perez    schedule 13.10.2017