Array only extends the non-generic version of IEnumerable, so will there be boxing and unboxing when a foreach loop goes through a value type array?
I am guessing not, because that would be lame. If my guess is right, then how does foreach go through a value type array? Does it not use the Array.GetEnumerator method? And if not, why does Array extends IEnumerable?
开发者_如何学JAVAThanks
Array
has a lot of special casing in the runtime. In particular it is pseudo-generic. i.e. if you specify a concrete array type like T[]
implement the generic collection interfaces like IEnumerable<T>
.
If I recall correctly it even supported non boxing iteration with foreach
before generics by having GetEnumerator
return a concrete type with a strongly typed Current
. This works since foreach
does not require the IEnumerator
/IEnumerable
interfaces, but works with correctly named members too.
So you can iterate over arrays with foreach
without boxing.
CodesInChaos's answer is incorrect. A value-type array is iterated without boxing because of special handling in the C# compiler, not special handling in the runtime. The C# compiler translates a foreach loop into a for loop when the static type of the iterated collection is an array type.
Also, your question is based on an incorrect assumption ("Array only extends the non-generic version of IEnumerable"). In fact, arrays implement the generic IEnumerable<T>
; it's just that this is done using explicit member implementation, for reasons of backward compatibility. (Also, the fact that arrays implement the generic interfaces is a case of special handling in the runtime; you will not see them in the definition of System.Array
when you decompile mscorlib.)
This means that if you have an array int[] a
, and you call a.GetEnumerator()
, you'll get a non-generic IEnumerator
reference. However, you can explicitly cast to get a generic IEnumerator<int>
reference: ((IEnumerable<int>)a).GetEnumerator()
.
精彩评论