Простое использование IEnumerator (с примером) - PullRequest
62 голосов
/ 05 сентября 2011

У меня проблемы с запоминанием того, как (но не почему) использовать IEnumerator s в C #.Я привык к Java с ее замечательной документацией, которая довольно неплохо объясняет новичкам.Поэтому, пожалуйста, потерпите меня.

Я пытался учиться на других ответах на этих досках, но безрезультатно.Вместо того, чтобы задавать общий вопрос, который уже задавался ранее, у меня есть конкретный пример, который бы прояснил для меня вещи.

Предположим, у меня есть метод, которому нужно передать объект IEnumerable<String>.Все, что нужно сделать методу - это объединить буквы roxxors до конца каждого String в итераторе.Затем он вернет этот новый итератор (конечно, исходный объект IEnumerable останется без изменений).

Как мне поступить?Ответ здесь должен помочь многим с основными вопросами об этих объектах в дополнение ко мне, конечно.

Ответы [ 5 ]

92 голосов
/ 05 сентября 2011

Вот документация по IEnumerator.Они используются для получения значений списков, где длина не обязательно известна заранее (даже если это может быть).Слово происходит от enumerate, что означает «отсчитывать или называть по одному».

IEnumerator и IEnumerator<T> предоставляется всеми интерфейсами IEnumerable и IEnumerable<T> (последний обеспечиваетоба) в .NET через GetEnumerator().Это важно, потому что оператор foreach предназначен для работы напрямую с перечислителями через эти методы интерфейса.

Так, например:

IEnumerator enumerator = enumerable.GetEnumerator();

while (enumerator.MoveNext())
{
    object item = enumerator.Current;
    // Perform logic on the item
}

Становится:

foreach(object item in enumerable)
{
    // Perform logic on the item
}

Что касается вашего конкретного сценария, то почти все коллекции в .NET реализуют IEnumerable.Из-за этого вы можете сделать следующее:

public IEnumerator Enumerate(IEnumerable enumerable)
{
    // List implements IEnumerable, but could be any collection.
    List<string> list = new List<string>(); 

    foreach(string value in enumerable)
    {
        list.Add(value + "roxxors");
    }
    return list.GetEnumerator();
}
18 голосов
/ 05 сентября 2011
public IEnumerable<string> Appender(IEnumerable<string> strings)
{
  List<string> myList = new List<string>();
  foreach(string str in strings)
  {
      myList.Add(str + "roxxors");
  }
  return myList;
}

или

public IEnumerable<string> Appender(IEnumerable<string> strings)
{
  foreach(string str in strings)
  {
      yield return str + "roxxors";
  }
}

с использованием конструкции или просто

var newCollection = strings.Select(str => str + "roxxors"); //(*)

или

var newCollection = from str in strings select str + "roxxors"; //(**)

, гдедва последних используют LINQ и (**) просто синтаксический сахар для (*).

8 голосов
/ 05 сентября 2011

Если я вас правильно понимаю, то в c # * магия yield return - это все, что вам нужно, я думаю.

, например

IEnumerable<string> myMethod(IEnumerable<string> sequence)
{
    foreach(string item in sequence)
    {
         yield return item + "roxxors";
    }
}
5 голосов
/ 05 сентября 2011

Я бы сделал что-то вроде:

private IEnumerable<string> DoWork(IEnumerable<string> data)
{
    List<string> newData = new List<string>();
    foreach(string item in data)
    {
        newData.Add(item + "roxxors");
    }
    return newData;
}

Простые вещи:)

4 голосов
/ 05 сентября 2011

Также вы можете использовать метод выбора LINQ:

var source = new[] { "Line 1", "Line 2" };

var result = source.Select(s => s + " roxxors");

Подробнее здесь Перечислим. Выберите метод

...