My understanding is System.Range
and System.Index
are going to be .NET Core 3.0 specific features.
That prevents me from creating a library, that targets .NET Standard 2.0 (for I need to support .NET 4.7), and implements range indexers for the types defined in it.
I think it is a huge problem, especially considering the next .NET Standard is not going to be implemented by .NET 4.8.
Are there any plans to deal with it?
Is the problem in the desire to implement range-based indexing for the core types like System.Array
? If so, are there ways to work around that? Can .NET Core 3.0 instead define System._Range
, and have hypothetical System.Range package implementing an implicit conversion System._Range
-> System.Range
? Any other alternatives?
Any other alternatives?
You can use multi-targeting. So you have a code path for .NET Core 3.0 and one for .NET Standard 2.0.
@gfoidl how would that work? I'd still need a System.ValueTuple
-like package for .NET Standard 2.0 for System.Range
to implement ranges. Otherwise consumers of my library will face name conflicts with other libraries.
If you are proposing to drop range indexing for .NET Standard 2.0, then that's exactly what I want to avoid.
I meant the latter, and don't know a better way.
/cc @terrajobst
@tarekgh can you PTAL
@lostmsu Index and Range are not in netstandard 2.0. These types will be in netstandard 2.1. You may look at https://github.com/dotnet/standard/pull/1018.
@tarekgh , yes, and that is the nature of the problem. The indexing feature of C# 8 will be unusable on .NET Framework.
It's not just the indexing feature of C# 8 being available on .NET Framework that I'm concerned about. (There are other C# 8 features that flat out won't ever work on .NET Framework 4.8. See Building C# 8.0 Blog).
But the core issue here is that you can't have a netstandard2.0
or less library that exposes APIs that will allow the indexing feature in C# 8 to work when it IS available (say in a .NET Core 3.0 app).
For example, in the System.Numerics.Tensors
library (which targets netstanard1.1
today), we'd like to have a Slice
method on a Tensor
. Since tensors are multi-dimensional, you need to have a collection of start
and stop
indices - basically exactly what System.Range
is. One for each dimension.
To expose the Slice
API, we need some way of specifying the range in each dimension you want to slice off the tensor. Without having System.Range
available, Numerics.Tensors
will need to come up with their own "Range-like API". Let's say ValueTuple<int, int>
. But here's the problem - is the 2nd int a Length or a stopping index? If it is a stopping index, is it inclusive or exclusive? Does it handle negative indices? etc. etc.
All of these problems would be solved if we had a common type that encapsulated these semantics. And we do have the type, we just aren't allowing libraries less than netstandard2.1
use it.
Any updates on a package for Range
and Index
?
In lieu of an official solution, I created my own unofficial one last month:
@terrajobst @jaredpar do we have the final call on that?
Also looking forward to a "backport" NuGet package for ranges in .NET Standard 2.0, just like System.Memory
or Microsoft.Bcl.HashCode
.
And here I wondered why I never get code style hints by VS for starting to use ranges... was because I also target classic .NET Framework... 馃憖
ping @terrajobst can you please take a look?
I've recently discussed this. The problem is this:
ValueTuple
was a bit of disaster. That's because we shipped an out of box (OOB) and in-box version on .NET Framework. This has caused significant pain with binding redirectcs and friends.Range
itself doesn't suffer from this because there is no version of .NET Framework that included it. We don't have any issues with pure OOBs (span, JSON) However, Range
depends on tuples 馃槥 One could maybe argue that (1) is a thing of the past as .NET Framework 4.7 includes it in-box (and we generally recommend to be on 4.7.2 to consume .NET Standard 2.0 binaries). We should test this, but I think an OOB for range seems doable.
@ericstj any other concerns?
I think we've created a pattern with the Microsoft.Bcl additions that solves the technical problems. I briefly looked at @bgrainger's solution and it follows this pattern. There is still the annoyance that the entire stack needs to target the framework with the component inbox to eliminate the need for the package, for example https://github.com/dotnet/runtime/issues/35984.
Most helpful comment
It's not just the indexing feature of C# 8 being available on .NET Framework that I'm concerned about. (There are other C# 8 features that flat out won't ever work on .NET Framework 4.8. See Building C# 8.0 Blog).
But the core issue here is that you can't have a
netstandard2.0
or less library that exposes APIs that will allow the indexing feature in C# 8 to work when it IS available (say in a .NET Core 3.0 app).For example, in the
System.Numerics.Tensors
library (which targetsnetstanard1.1
today), we'd like to have aSlice
method on aTensor
. Since tensors are multi-dimensional, you need to have a collection ofstart
andstop
indices - basically exactly whatSystem.Range
is. One for each dimension.To expose the
Slice
API, we need some way of specifying the range in each dimension you want to slice off the tensor. Without havingSystem.Range
available,Numerics.Tensors
will need to come up with their own "Range-like API". Let's sayValueTuple<int, int>
. But here's the problem - is the 2nd int a Length or a stopping index? If it is a stopping index, is it inclusive or exclusive? Does it handle negative indices? etc. etc.All of these problems would be solved if we had a common type that encapsulated these semantics. And we do have the type, we just aren't allowing libraries less than
netstandard2.1
use it.