While reading through the design spec for Span<T>, I noticed that there are already two distinct types: Span<T> and ReadOnlySpan<T>. I suppose in the future there may be more. Usually the way to generalize multiple implementations is via interfaces. That way developers can code to the interface and swap out implementations as necessary.
Has there been any consideration for implementing a common interface ISpan<T> that Span<T> and ReadOnlySpan<T> can implement? In addition to advantages of coding to interfaces, it also allows extending and building new types without necessarily breaking existing implementations.
CC @terrajobst
Since Span<T> is meant to reduce allocations and improve scalability it's a struct meant to be stack-only.
When you assign a struct to an interface you box it, which negates the whole idea of reducing allocations.
You could still have the interface and use generic methods where the interface is only used as a constraint:
void Foo<T, U>(T span) where T : ISpan<U>
That would avoid the need to box. But the interface just being there will make it very easy for developers to shoot themselves in the foot.
Span can't be used in Generics either; so the interface isn't useful for a generic constraint
The interop between the types is done via implicit and explicit casts; so if your function takes a ReadOnlySpan then you can pass it a Span as there is an implicit conversion.
You can't however pass a ReadOnlySpan to a function that takes a Span as there is no conversion.
@benaadams
Span can't be used in Generics either
Why? ref?
https://github.com/dotnet/corefxlab/pull/738#issuecomment-236234999
byref-based span has the same limitation as byrefs and other byref-like types - it cannot be used as generic argument.
contravariant position does not prevent it from being stored as a field, etc.
Most helpful comment
https://github.com/dotnet/corefxlab/pull/738#issuecomment-236234999