我明白为什么ReadOnlySpan
不能用作泛型类的类型参数。ReadOnlySpan
仅是堆栈,因此它不能用作字段类型,字段成员像其容器对象一样存在于堆中。但是返回值和参数始终只是堆栈,所以为什么ReadOnlySpan
不能用作泛型委托和泛型方法的类型参数?
这里有一个例子来说明我所说的:
using System;
namespace ConsoleApp7
{
class Program
{
public delegate TResult MyFunc<TResult>(ReadOnlySpan<char> arg);
static int GetSpanLength(ReadOnlySpan<char> span)
{
return span.Length;
}
static void Main(string[] args)
{
var span = "hello".AsSpan();
MyFunc<int> func1 = GetSpanLength;
var result1 = DoSomething(func1, span);
// The type 'ReadOnlySpan<char>' may not be used as a type argument
Func<ReadOnlySpan<char>, int> func2 = GetSpanLength;
//The type 'ReadOnlySpan<char>' may not be used as a type argument
var result = DoSomething<int, ReadOnlySpan<char>>(func2, span);
}
static TResult DoSomething<TResult, T>(Func<T, TResult> func, T arg)
{
return func(arg);
}
static TResult DoSomething<TResult>(MyFunc<TResult> func, ReadOnlySpan<char> arg)
{
return func(arg);
}
}
}
这是非常不幸的,因为它迫使我有两个相同版本的 DoSomething 方法,使我的代码非常湿。
注意:对于面向 .NET Framework 的项目,您需要安装 System.Memory Nuget 包。
This post https://adamsitnik.com/Span/#span-must-not-be-a-generic-type-argument亚当·西特尼克说
让我们考虑以下 C# 代码:
Span<byte> Allocate() => new Span<byte>(new byte[256]);
void CallAndPrint<T>(Func<T> valueProvider) // no generic requirements for T
{
object value = valueProvider.Invoke(); // boxing!
Console.WriteLine(value.ToString());
}
void Demo()
{
Func<Span<byte>> spanProvider = Allocate;
CallAndPrint<Span<byte>>(spanProvider);
}
正如您所看到的,今天无法确保非装箱要求,如果
我们允许 Span 为泛型类型参数。其中一种可能
解决方案可能是引入新的通用约束:stackonly。但
那么所有托管编译器都必须尊重它并确保
缺乏拳击和其他限制。这就是为什么决定
只是禁止使用 Span 作为通用参数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)