2015-08-10 5 views
2

, когда я перехожу к определению списка <> Я вижу, что у него есть публичный блок Enumerator, который реализует интерфейсы IEnumerator<T>, IDisposable и IEnumerator.Где общий список <> реализует сброс?

IEnumerator должен принудительно выполнить сброс - кроме Current и MoveNext. Но реализованы только Current и MoveNext. Как это может быть?
Где я могу найти Reset() из списка <>?

var list = new List<int>(); 
list.Add(23); 
list.Add(44); 
var Enumerator = list.GetEnumerator(); 
while (Enumerator.MoveNext()) 
{ 
    Console.WriteLine(Enumerator.Current); 
} 
Enumerator. 

И когда я пытаюсь его в коде нет Reset():
Ok - Я попытался показать скриншот, но они не позволяют мне.
Но копирование над кодом не показывает Reset-Method после Dot-operator (.) перечислителя.

Может кто-нибудь знать и пролить свет на это?

Я вижу, что он вызывает сброс IEnumerator, который является частью mscorlib.

var list = new List<int>(); 
list.Add(23); 
list.Add(44); 
var Enumerator = list.GetEnumerator(); 
Enumerator.MoveNext(); 
Enumerator.MoveNext(); 
Console.WriteLine(Enumerator.Current); 
((IEnumerator<int>)Enumerator).Reset(); 
Enumerator.MoveNext(); 

И все же, поскольку IEnumerator - это интерфейс, как код может быть вызван им?
Сброс() в IEnumerator должен быть просто определением, а реализация остается тем, кто использует интерфейс.
Но как-то здесь фактическая функциональность обеспечивается только определением интерфейса, который будет реализован. Нигде я не вижу фактической реализации - и эту часть я не понимаю.

ответ

4

Это explicitly implemented, as shown in the documentation, as is IEnumerator.Current. Другими словами, вы можете вызвать метод только для значения с типом времени компиляции IEnumerator.

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

// Casing changed to be more conventional 
var enumerator = list.GetEnumerator(); 
((IEnumerator)enumerator).Reset(); 

Однако, что бы тогда поле значение равно (как List<T>.Enumerator это структура), что сделало бы бессмысленным. Неясно, интересуетесь ли вы очевидным отсутствием метода Reset, но в целом я бы настоятельно советовал вам не полагаться на IEnumerator.Reset - он очень часто не реализован, и IMO он не должен был быть частью интерфейс для начала с ...

+0

Спасибо, и да, я наткнулся на нехватку аппаранта Reset() –

+0

Привет, мне пришлось отредактировать исходное сообщение, потому что в форматировании комментария ограничено. –

+0

@ AndiTruman: теперь вы задали совершенно другой вопрос, как вторую часть, - я предлагаю вам удалить его снова из вопроса, так как это принципиально «как работают интерфейсы», который, как я подозреваю, рассматривается в другом месте ... –

1

Вы думаете, что используете интерфейс IEnumerator <>, но это не так. Тип вывода становится лучше вас, тип переменной Enumerator равен фактически List.Enumerator <>, тип структуры. Используйте интерфейс, и вы не будете иметь никаких проблем:

IEnumerator<int> Enumerator = list.GetEnumerator(); 
    while (Enumerator.MoveNext()) { 
     Console.WriteLine(Enumerator.Current); 
    } 
    Enumerator.Reset(); // Fine 

Это не работает на List.Enumerator <> потому, что Microsoft намеренно скрывала реализацию метода Reset(), сделав его закрытым. Обратите внимание, как итераторы для других классов коллекций, таких как Dictionary и HashSet, ведут себя так же.

Это может быть использование пояснений. IEnumerator инкапсулирует итератор только вперед и является основой, на которой был построен дом Linq. Метод Reset() - это проблема, которая больше не является строго форвардной. Вы перемещаете итератор назад.На практике вы узнаете, что во многих случаях попытка вызвать Reset() создает исключение NotImplementedException. Не проблема для List, легко вернуться. Большая проблема для Linq.

IEnumerator должен был разработан без метода Reset(). Но выбор дизайнеров .NET не был, это было прибито до 1996 года, задолго до того, как кто-то начал работать над .NET. Итераторы были существующей концепцией в COM Automation. Какая была модель расширения для Visual Basic версии 4, она заменила 16-битную модель VBX.

Дико популярный, практически любой язык исполнения на Windows его реализует. И все еще очень сильно используется в .NET-программах. Умело скрытый в большинстве случаев, никоим образом не сказать, что вы используете его, когда вы помещаете WebBrowser в свой пользовательский интерфейс, например. Разработчики .NET были вынуждены внедрить его, чтобы иметь возможность заставить программистов перейти на .NET. Также является источником очень сложного интерфейса ICloneable.

+0

Спасибо вам обоим , Таким образом, реализация универсального IEnumerator все еще существует и также доступна - просто скрыта. –