What concrete type does 'yield return' return?
What is the开发者_运维知识库 concrete type for this IEnumerable<string>
?
private IEnumerable<string> GetIEnumerable()
{
yield return "a";
yield return "a";
yield return "a";
}
It's a compiler-generated type. The compiler generates an IEnumerator<string>
implementation that returns three "a" values and an IEnumerable<string>
skeleton class that provides one of these in its GetEnumerator
method.
The generated code looks something like this*:
// 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();
}
}
Or maybe, as SLaks says in his answer, the two implementations end up in the same class. I wrote this based on my choppy memory of generated code I'd looked at before; really, one class would suffice, as there's no reason the above functionality requires two.
In fact, come to think of it, the two implementations really should fall within a single class, as I just remembered the functions that use yield
statements must have a return type of either IEnumerable<T>
or IEnumerator<T>
.
Anyway, I'll let you perform the code corrections to what I posted mentally.
*This is purely for illustration purposes; I make no claim as to its real accuracy. It's only to demonstrate in a general way how the compiler does what it does, based on the evidence I've seen in my own investigations.
The compiler will automatically generate a class that implements both IEnumerable<T>
and IEnumerator<T>
(in the same class).
Jon Skeet has a detailed explanation.
The concrete implementation of IEnumerable<string>
returned by the method is an anonymous type generated by the compiler
Console.WriteLine(GetIEnumerable().GetType());
Prints :
YourClass+<GetIEnumerable>d__0
精彩评论