Open ekolis opened 3 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
I'm pretty sure this worked in .NET Framework.
Nope ;-) Multidimensional arrays have always implemented IEnumerable
, not IEnumerable<T>
.
Tagging subscribers to this area: @eiriktsarpalis See info in area-owners.md if you want to be subscribed.
Author: | ekolis |
---|---|
Assignees: | - |
Labels: | `area-System.Linq`, `untriaged` |
Milestone: | - |
I'm pretty sure this worked in .NET Framework.
Nope ;-) Multidimensional arrays have always implemented
IEnumerable
, notIEnumerable<T>
.
Oh, really? Could have sworn they implemented the latter before! Wonder why they don't, anyway?
IEnumerable<T>
for arrays is implemented via "runtime magic". It is not pay-for-play in all scenarios and it is pretty complex, and it would be even more complex for multidimensional arrays. If we had a time machine and can do this again, there is a good chance we would pick a different design, e.g. static IEnumerable<T> AsEnumerable<T>(this T[] array)
extension method.
If we had a time machine and can do this again, there is a good chance we would pick a different design, e.g. static IEnumerable
AsEnumerable (this T[] array) extension method.
Is that something we could consider for multi-dimensional arrays? F# just introduced multi-dimensional array slicing so perhaps it makes sense to add enumeration support for submatrices (either by row or by column) by passing in a pair of Range
parameters (in the case of 2D arrays).
@joktas It is not pay-for-play in all scenarios and it is pretty complex
- isn't it the same for IEnumerable?
IEnumerable
is not generic interface. It is implemented on System.Array
without any runtime magic.
IEnumerable<T>
is generic. It is what makes the implementation very complex for arrays.
If we were to do something here, I think it should be set of AsEnumerable
-style extension methods that create enumerable view of the multidimensional array.
@jkotas It is implemented on System.Array without any runtime magic.
- I wonder where it's implemented for multidimensional arrays?
I wonder where it's implemented for multidimensional arrays?
The non-generic implementation is shared between single-dimensional and multi-dimensional arrays: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Array.cs#L2406-L2409 and https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Array.Enumerators.cs#L10-L65
I think this issue would be better named as "Allow multidimensional arrays to implement IEnumerable<T>
".
Onto the real things, I think a MDGenericArrayEnumerator<T>
would be possible, just like SZGenericArrayEnumerator<T>
. As for the implementation details, if I recall correctly, MD arrays are also stored sequentially, so a Span<T>
would work, provided the Length
property. It could also require a new Span<T>(Array)
constructor. Overall, MD arrays need some work be done to come in par with SZ arrays.
Description
Try to run this code:
Expected behavior: Fred and Francine are printed.
Actual behavior: Compile error on the LINQ call:
Error CS1061 'string[*,*]' does not contain a definition for 'Where' and no accessible extension method 'Where' accepting a first argument of type 'string[*,*]' could be found (are you missing a using directive or an assembly reference?)
Configuration
.NET 5 Windows 10 Home 64 bit x64
Regression?
I'm pretty sure this worked in .NET Framework.
Other information
Workaround: call
Cast
on the array to convert it to anIEnumerable<T>
: