Allow yield when return type is any implementer of IEnumerable #8344
Answered
by
KennethHoff
seanblue
asked this question in
Language Ideas
Replies: 2 comments 1 reply
-
Why would this be necessary? You can just create the collection within the method and return it directly. You have no need for the mechanics of a coroutine, which exist specifically for the deferred behavior you're attempting to avoid. |
Beta Was this translation helpful? Give feedback.
0 replies
-
List<int> MyMethod()
{
return [..Inner()];
static IEnumerable<int> Inner()
{
// Yield as much as you want here.
}
} |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
seanblue
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
yield
is often a convenient way to return a collection of data, but right now it can only be used when the return type isIEnumerable
. If you want to avoid multiple enumeration, this means having to abandonyield
to build up aList
manually or callingToList
after calling the method.I think it would be convenient if you could use
yield
when the return type is any implementer ofIEnumerable
and not justIEnumerable
itself.The tradeoff here is of course that it'll enumerate the entire collection up front whereas when the return is
IEnumerable
it won't, though I think that should be obvious based on the difference in return types.I'm trying to figure out if there would be any potential performance improvement or reduced memory allocation by directly constructing/returning
List<T>
instead of callingToList
on theIEnumerable<T>
since this would strengthen the argument for allowing this, but I'm honestly not sure it would make much difference. Putting aside the minor performance savings from avoiding Linq that is.In theory this could work in a couple ways:
IEnumerable
into the constructor of any type that allows it likeList<T>
andHashSet<T>
.Add
fromICollection<T>
and it is syntactic sugar for constructing the collection type and callingAdd
everywhere that doesyield return
.I suppose calling it syntactic sugar implies there's no performance or memory benefit, but maybe there is in some way I'm not seeing.
The only performance/memory benefit I see is if
yield return all
was also implemented (#378) andAddRange
was also a required component for support, because then it could callAdd
foryield return
andAddRange
foryield return all
which can allow it to expand the size of the backing array correctly all at once instead of one item at a time. But that would only work when both the outermost yield method is returning someICollection
and so is the inner yield method that is being returned viayield return all
, since that's the only way the size would be known and used up front. Not sure how common that would be, so maybe it's a stretch to call it a benefit.The only other consideration I have is whether this could work in conjunction with natural type support for collection expressions (#7913). I'd be interested to know if this could just dovetail with that feature to be implemented with little effort for any collection types that are inferable as part of natural type support for collection expressions.
Beta Was this translation helpful? Give feedback.
All reactions