Каков конкретный тип для этого IEnumerable<string>
?
private IEnumerable<string> GetIEnumerable()
{
yield return "a";
yield return "a";
yield return "a";
}
Это тип, созданный компилятором . Компилятор создает реализацию IEnumerator
, которая возвращает три значения «a» и скелетный класс IEnumerable
, который предоставляет одно из них в своем GetEnumerator
метод.
Сгенерированный код выглядит что-то так *:
// No idea what the naming convention for the generated class is --
// this is really just a shot in the dark.
class GetIEnumerable_Enumerator : IEnumerator<string>
{
int _state;
string _current;
public bool MoveNext()
{
switch (_state++)
{
case 0:
_current = "a";
break;
case 1:
_current = "a";
break;
case 2:
_current = "a";
break;
default:
return false;
}
return true;
}
public string Current
{
get { return _current; }
}
object IEnumerator.Current
{
get { return Current; }
}
void IEnumerator.Reset()
{
// not sure about this one -- never really tried it...
// I'll just guess
_state = 0;
_current = null;
}
}
class GetIEnumerable_Enumerable : IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
return new GetIEnumerable_Enumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Или, может быть, как говорит SLaks в своем ответе, две реализации попадают в один и тот же класс. Я написал это на основе моей изменчивой памяти сгенерированного кода, на который я смотрел раньше; действительно, одного класса будет достаточно, поскольку нет причин, по которым вышеуказанная функциональность требует двух.
На самом деле, если подумать, две реализации действительно должны попадать в один класс, так как я только что вспомнил, что функции, которые используют операторы yield
, должны иметь возвращаемый тип из либо IEnumerable
, либо IEnumerator
.
В любом случае, я позволю вам внести исправления в код того, что я мысленно отправил.
* Это чисто для иллюстративных целей; Я не претендую на его истинную точность. Это только для того, чтобы в общих чертах продемонстрировать, как компилятор делает то, что он делает, на основе свидетельств, которые я видел в своих собственных исследованиях.
Конкретная реализация IEnumerable
, возвращаемая методом, является анонимным типом, сгенерированным компилятором
Console.WriteLine(GetIEnumerable().GetType());
Выводит:
YourClass+<GetIEnumerable>d__0
Компилятор автоматически сгенерирует класс, который реализует как IEnumerable
, так и IEnumerator
(в том же классе) .