为什么调用采用 Span<T> 和 T[] 的泛型方法无法推断类型参数?
Why calling a generic method that takes Span<T> with T[] cannot infer a type argument?
我创建了一个将 Span<T>
/ReadOnlySpan<T>
作为参数的通用方法。
我想用一个数组调用我的方法,但这是一个错误。 (代码示例中的错误 CS0411,int b
。)
我认为编译器在没有类型参数的情况下将 Array 转换为 Span,因为存在从 T[]
到 Span<T>
/ReadOnlySpan<T>
的隐式转换,但事实并非如此。为什么?
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)];
}
}
我将此作为答案发布,但这是我的有根据的猜测,而不是实际知识。
我假设这是因为,虽然存在从 T[]
到 ReadOnlySpan<T>
的隐式转换,但编译器看不到它,因为它不知道 T
是什么是因为它没有 ReadOnlySpan<T>
来推断它。这可能是先有鸡还是先有蛋的情况,即在不知道 T
的情况下无法获得 ReadOnlySpan<T>
,但在不知道 ReadOnlySpan<T>
的情况下无法获得 T
。第一个和最后一个调用有效,因为这两件事中只有一个是未知的,但在第二个调用中两者都是未知的,所以你运气不好。您要么必须指定通用类型,要么创建您自己的 ReadOnlySpan<T>
.
我创建了一个将 Span<T>
/ReadOnlySpan<T>
作为参数的通用方法。
我想用一个数组调用我的方法,但这是一个错误。 (代码示例中的错误 CS0411,int b
。)
我认为编译器在没有类型参数的情况下将 Array 转换为 Span,因为存在从 T[]
到 Span<T>
/ReadOnlySpan<T>
的隐式转换,但事实并非如此。为什么?
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)];
}
}
我将此作为答案发布,但这是我的有根据的猜测,而不是实际知识。
我假设这是因为,虽然存在从 T[]
到 ReadOnlySpan<T>
的隐式转换,但编译器看不到它,因为它不知道 T
是什么是因为它没有 ReadOnlySpan<T>
来推断它。这可能是先有鸡还是先有蛋的情况,即在不知道 T
的情况下无法获得 ReadOnlySpan<T>
,但在不知道 ReadOnlySpan<T>
的情况下无法获得 T
。第一个和最后一个调用有效,因为这两件事中只有一个是未知的,但在第二个调用中两者都是未知的,所以你运气不好。您要么必须指定通用类型,要么创建您自己的 ReadOnlySpan<T>
.