foreach с классами, которые не 'осуществляют' IEnumerable/IEnumerator

Я увидел комментарий Equiso в одном из моих ответов с интересной деталью и дело в том, что он осуществил интерфейс (Или часть ее) так, что оператор не использует : справа от имени объекта.

Он предоставлял следующий код:

public class TestEnumerator
{
    private int _veces;
    public TestEnumerator(int veces) { _veces = veces; }
    public object Current  { get { return "Hola " + _veces; } }
    public bool MoveNext() { return _veces-- > 0; }
}

public class Test
{
    public TestEnumerator GetEnumerator() { return new TestEnumerator(10); }
}

public static void Main()
{
    var test = new Test();

    foreach (var x in test)
        Console.WriteLine(x);
}

Действительно вывод - ожидаемый:

Hola 9
Hola 8
Hola 7
Hola 6
Hola 5
Hola 4
Hola 3
Hola 2
Hola 1
Hola 0

То, что эквивалентное осуществлению одной IEnumerable и IEnumerator в Ваших соответствующих классах. Как он назван этим типом осуществления? Ввиду того, что это класс с enumerador, но не коллекция, он сказал бы, что это осуществление пополам IEnumerable.

2
задан 13.04.2017, 16:00
2 ответа

В соответствии с foreach, in (C#):

Выражение с коллекцией или договоренностью. Тип элемента коллекции должен быть преобразуемым в тип идентификатора. Не использовать выражение, которое оценивается в null.
Оцени в тип, который осуществляет IEnumerable или тип, который он признает методом GetEnumerator. В последнем случае, будь должен возвращаться уже будьте типом, который осуществляет IEnumerator или который признает всеми методами, определенными в IEnumerator.

Код, о котором ты упомянул, выполняет последний случай. Метод Reset() он не нуждается в том, чтобы быть осуществленным обязательно.

В самом деле, решение foreach ее forma:1

foreach (V v in x) embedded-statement

она расширена тогда в:

{
    E e = ((C)(x)).GetEnumerator();
    try {
       V v;
       while (e.MoveNext()) {
           v = (V)(T)e.Current;
           embedded-statement
       }
    }
    finally {
       ... // Dispose of e
    }
}

Переменная e он не является видимым или доступным с первоначального кода. Переменная v он только чтения во впитанном решении (embedded-statement).


Замечания

  1. См. Те C# Программинг Лангвахе (Коверинг C# 4.0) Андерса Ехльсберг, Мадс Торхерсен, Скотта Вилтэмут, Питер Голд, pág. 519.
4
ответ дан 24.11.2019, 13:48

Здесь

Iteradores (C# и Visual Basic)

о нем упоминают

Создав iterador для класса или struct, не нужно осуществлять интерфейс полного IEnumerator. Когда составитель обнаруживает iterador, он производит автоматически методы Current, MoveNext, и Dispose интерфейса IEnumerator или IEnumerator.

Я понимаю, что foreach используй Current, MoveNext() и GetEnumerator() но он достигает с этого ему, не санкционируй, что был интерфейс IEnumerable и IEnumerator будьте объявлены, так как ты равен, они выставляют функциональность, в которой iteraccion нуждается

How to make в Визуальный C# class usable in в foreach statement

Правильное состояло бы в том, чтобы определять интерфейсы, которые они гарантируют, что класс был iterable

using System;
using System.Collections;

public class Program
{
    public static void Main()
    {
        var test = new Test();

        foreach (var x in test)
            Console.WriteLine(x);

    }
}

public class TestEnumerator : IEnumerator 
{
    private int _veces;
    public TestEnumerator(int veces) { _veces = veces; }
    public object Current  { get { return "Hola " + _veces; } }
    public bool MoveNext() { return _veces-- > 0; }

    public void Reset(){ _veces = 0; }
}

public class Test : IEnumerable
{
    public IEnumerator GetEnumerator() { 
        return (IEnumerator)new TestEnumerator(10); 
    }
}
2
ответ дан 24.11.2019, 13:48
  • 1
    Если s и # 233; что является правильным осуществлять их, но, и #191; Составитель C # замечает, когда я хочу направить класс iterable с foreach? – NaCl 20.07.2016, 19:40
  • 2
    просвет, это - именно то, что я комментирую, и то, что упоминает о соединении, .net может определять из-за методов, которые он выставляет, что это класс, который может быть повторенным, поэтому не необходимо осуществлять ее полной формы – Leandro Tuttini 20.07.2016, 19:45

Теги

Похожие вопросы