我理解为什么 ReadOnlySpan
不能用作泛型类的类型参数。 ReadOnlySpan
只是堆栈,因此它不能用作字段类型,字段成员像它的容器对象一样存在于堆中。然而,返回值和参数始终只是堆栈,那么为什么 ReadOnlySpan
不能用作泛型委托(delegate)和泛型方法的类型参数?
这里有一个例子可以说明我在说什么:
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 方法,使我的代码非常 WET。
注意:对于面向 .NET Framework 的项目,您需要安装 System.Memory Nuget 包。
最佳答案
这post来自 Adam Sitnik 说
Let’s consider following C# code:
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); }
As you can see the non-boxing requirement can not be ensured today if we allow the Span to be generic type argument. One of the possible solutions could be to introduce new generic constraint: stackonly. But then all the managed compilers would have to respect it and ensure the lack of boxing and other restrictions. This is why it was decided to simply forbid using Span as a generic argument.
关于c# - 为什么 ReadOnlySpan 不能用作泛型委托(delegate)和泛型方法的类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53155438/