I created a generic method that takes Span<T>
/ReadOnlySpan<T>
as a parameter.
I want to call my method with an array, but it is an error. (error CS0411, int b
in the code example.)
I thought that compiler converts Array to Span without a type argument, because an implicit conversion from T[]
to Span<T>
/ReadOnlySpan<T>
exists, but it is not. Why?
int[] items = { 1, 2, 3 };
int a = Random.Shared.NextItem(items);
// -> what I want that implicit conversion happens but this is not generic.
int b = Random.Shared.NextItemGeneric(items);
// -> error CS0411: The type arguments for method 'RandomExtensions.NextItemGeneric<T>(Random, ReadOnlySpan<T>)'
// cannot be inferred from the usage. Try specifying the type arguments explicitly.
int c = Random.Shared.NextItemGeneric<int>(items);
// -> ok
internal static class RandomExtensions {
public static int NextItem(this Random random, ReadOnlySpan<int> items) {
return items[random.Next(items.Length)];
}
public static T NextItemGeneric<T>(this Random random, ReadOnlySpan<T> items) {
return items[random.Next(items.Length)];
}
}
CodePudding user response:
I'm posting this as an answer but it is an educated guess on my part rather than actual knowledge.
I would assume that it's because, while there is an implicit conversion from T[]
to ReadOnlySpan<T>
, the compiler can't see that because it doesn't know what T
is because it doesn't have a ReadOnlySpan<T>
to infer it from. It's probably a chicken and egg situation, i.e. it can't get a ReadOnlySpan<T>
without knowing T
but it can't get T
without a ReadOnlySpan<T>
. The first and last calls work because only one of those two things is unknown but in the second call both are unknown, so you're out of luck. You'll either have to specify the generic type or create your own ReadOnlySpan<T>
.