It's been established that the compiler can do duck typing to remove some overhead when iterating over a List or an Array (see Duck typing in the C# compiler), as those types implement their IEnumerator as a stack-allocated struct.
Is this the case even when the type is generic, but constrained to implement IEnumerable?
To give more specifity, could option B run with less overhead than A?
A:
public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> collection)
{
foreach (var subCollection in collection)
foreach (var element in subCollection)
yield return element;
}
B:
public static IEnumerable<T> Flatten<TList, T>(this TList collection)
where TList : IEnumerable<IEnumerable<T>>
{
foreach (var subCollection in collection)
foreach (var element in subCollection)
yield return element;
}
No, basically. The only use for "B" is when the TList
itself is actually a struct
; the IL can then use "constrained call" to call the original GetEnumerator()
without any part having to box the original struct TList
value.
But: once you've called GetEnumerator()
, you're back into IEnumerator<T>
land, and it will not use the custom iterator.
All of which is mostly moot in this case, because iterator blocks are also fairly "allocatey". So... if avoiding boxing the TList
is your concern, you are presumably obsessive about allocations: in which case you wouldn't write the iterator block this way, either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With