Почему Enumerator использует IEnumerator, но никогда не реализует какой-либо метод этого интерфейса в C#?

Насколько я знаю, если вы используете интерфейс, вы должны реализовать все определения внутри интерфейса, в этом случае, просматривая структуру Enumerator, я заметил, что эта структура использует интерфейс IEnumerator:

public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
  public T Current { get;}
  public void Dispose();
  public bool MoveNext();
}

И IEnumerator определяется следующим образом:

public interface IEnumerator
{
  object Current { get; }
  bool MoveNext();
  void Reset();
}

Но я не вижу никакой реализации IEnumerator в Enumerator, как это возможно?

Более того, я пытаюсь определить свою собственную структуру и пытаюсь использовать IEnumerator так же, как это делает структура Enumerator:

public struct myOwnStruct : IEnumerator
{
  public  Current { get;}
  void Reset();
  public bool MoveNext();
}

И компилятор говорит, что для IEnumerator нет реализации.

Итак, как объяснить, что структура Enumerator использует интерфейс, но никогда не предоставляет реализацию?


person pepe    schedule 06.06.2016    source источник
comment
Они там реализованы как приватные методы. Инструмент, который вы используете, отображает только общедоступные. Поищите явную реализацию интерфейса в вашей любимой книге по языку C#.   -  person Hans Passant    schedule 06.06.2016
comment
IEnumerator должен быть реализован вашим классом коллекции. Таким образом, все, что реализует IEnumerable, должно будет реализовать IEnumerator. Предполагается, что перечислитель предназначен для перечисления вашей коллекции, поэтому вам нужно реализовать его в зависимости от того, как работает ваша коллекция!   -  person Callum Linington    schedule 06.06.2016
comment
Если вы собираетесь публиковать код и спрашивать об ошибках компилятора, убедитесь, что код действительно выдает рассматриваемое сообщение об ошибке, а не множество других ошибок. У последней структуры нет тела для Dispose или MoveNext, а T не определено.   -  person Lasse V. Karlsen    schedule 06.06.2016
comment
О, отлично!!, это объясняет это, и какой инструмент я могу использовать, чтобы увидеть реализацию частных методов?   -  person pepe    schedule 06.06.2016
comment
Вы просматривали источник ссылок?   -  person Lasse V. Karlsen    schedule 06.06.2016
comment
Нет, никогда не смотрел, спасибо за помощь!!, я посмотрю эту ссылку.   -  person pepe    schedule 06.06.2016
comment
@HansPassant Я чувствую, что это противоречит цели интерфейсов, по крайней мере, с точки зрения класса типов; если вы не можете получить доступ к методам, гарантированным контрактом, их может и не быть, не так ли?   -  person a p    schedule 06.06.2016
comment
Что ж, неправильная точка зрения. Весь смысл интерфейсов в том, чтобы полностью скрыть их реализацию. И вы, безусловно, можете получить доступ к этим закрытым методам реализации через ссылку на интерфейс.   -  person Hans Passant    schedule 06.06.2016
comment
@ap Они доступны, но только при первом приведении к определенному интерфейсу, который определяет методы. Это полезно для предоставления различных реализаций в зависимости от того, какой интерфейс используется. Это необходимо в случае IEnumerable<T>, потому что есть 2 метода GetEnumerator, которые отличаются только типом возвращаемого значения, поэтому вы должны реализовать хотя бы один явно.   -  person Kyle    schedule 06.06.2016


Ответы (2)


explicit interface implementation как раз используется в таких случаях, когда вам нужно реализовать два интерфейса с одинаковой сигнатурой метода (Current) и разными типами возвращаемых значений (есть и другие варианты использования, например, скрытие).

Проще говоря, это единственный способ сделать это (компилятор не позволяет вам определить два метода, которые технически «одинаковы»).

Подписи и перегрузка

Сигнатура метода специально не включает тип возвращаемого значения.

person NSGaga-mostly-inactive    schedule 06.06.2016

`Enumerator` provides explicit implementation of `IEnumerator<T>`. Implicit implementation is in the format InterfaceName.Method. So Enumerator have void  `object Ienumerator.Current { get{/*implementation*/} }` and etc.

Если вы хотите реализовать IEnumerator в своей собственной структуре, у вас есть два варианта:

public struct myOwnStruct : IEnumerator
{
  public  Current { get{/* implementation*/}}
  public void Reset(){}
  public bool MoveNext(){return true;}
}

or

 public struct myOwnStruct : IEnumerator
    {
      IEnumerator.Current { get{/* implementation*/}}
      void IEnumerator.Reset(){}
      bool IEnumerator.MoveNext(){return true;}
    }

Дополнительную информацию о явной и неявной реализации интерфейса вы можете найти здесь: явные и неявные реализации интерфейса

person Radin Gospodinov    schedule 06.06.2016