[Proposal]: Improve binding of spread elements in Collection Expressions #7782
Replies: 7 comments 6 replies
-
Just do |
Beta Was this translation helpful? Give feedback.
-
Put another way. We didn't do any support for this when we did linq (and that was much closer in time to the non-generic collections). The answer even then was |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi This isn't only about the old collections, but it would also be good for any type that exposes an indexer, as iterating with indexer is usually better and doesn't allocate an IEnumerator.
When you do that, you lose the "known length" of the collection expression. |
Beta Was this translation helpful? Give feedback.
-
I don't see why that would be the case. An enumerator has private access to the contents of the collection.
You shouldn't. .Cast should preserve Count information. |
Beta Was this translation helpful? Give feedback.
-
As mentioned, it may or it may not be. We're not going to invest in heuristics that can just as easily make things worse. As Linq itself didn't invest here, and that's been fine for literally 20 years, we're not going to start now :-) |
Beta Was this translation helpful? Give feedback.
-
This suggestion seems good to me. I remember this coming up a while ago. It would bring more consistency to the language. Pattern matching already has this type of recognition of the element type of a nongeneric collection, and it works via the indexer property type exactly the way you're describing: using System.Collections;
if (new C() is [var x])
{
x.ThisIsStronglyTypedViaTheIndexer();
}
class ElementType
{
public void ThisIsStronglyTypedViaTheIndexer() { }
}
class C : IEnumerable
{
public int Count => throw new NotImplementedException();
public ElementType this[int index] => throw new NotImplementedException();
public IEnumerator GetEnumerator() => throw new NotImplementedException();
} What I'm not sure about is the priority of supporting nongeneric collections, but this type of feedback is exactly what we need to get a sense of the need. |
Beta Was this translation helpful? Give feedback.
-
I thought it would be good to flesh out some of my previous off-the-cuff comments. I can definitely see where this idea is coming from, and the sorts of scenarios it wants to enable. That said, this runs into a common design question of how to break problems up, and how to best align those constituent parts with the language as is, and where we want the language to be. So, when it comes to collection expressions, spreads, and untyped IEnumerables, there is a lot of overlap with many parts of the language, and many of the design choices we've aligned with over the years. First (and to me, foremost), we took a fairly strong stance on the design group that So, in a very real sense, adding such a 'bridging' feature would be taking us away from that intuition and design alignment. We would now be saying "you should think of this as akin to So, to me, my view here is that it's not desirable to approach this from a direction of trying to special case these collections solely for collection expressions. Instead, my personal view is that if we were to tackle this space, we'd want to do so in a way that allowed them to gain better functionality in a consistent way across the language. So, for this sort of feature, instead of saying that a collection-expr could spread these in a certain way, it would be more desirable to just say "all collections like this are iterable in this fashion". If we did that, then something like a collection-expression would more 'fall out'/'light up'. Now, that said, i still land on the position that i think the existing solutions to this space are sufficient. There are two that i can think of right off the bat:
Thanks for the feedback! We'll definitely roll this into our future thinking in this space. But, of course, we can't promise anything will necessarily be done here specifically. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Collection expressions have the ability to spread the elements of any object that implements IEnumerable or IEnumerable<T> into the collection. However, many old collection types from BCL do not implement the generic IEnumerable<T>, and because of that, they're recognized as
object
collections, and can't be spread into collections of their specific type.The idea is that, when encountering a spread element, the compiler could check for the presence of an indexer, in addition to the Length/Count property that it already checks, and if both are present, then it iterates the collection using the indexer, instead of using GetEnumerator/MoveNext. Also it would recognize the type of the spread element as the return type of the indexer, instead of
object
.Beta Was this translation helpful? Give feedback.
All reactions