c# - 为什么 ReadOnlySpan 不能用作泛型委托(delegate)和泛型方法的类型参数?

标签 c# dry

我理解为什么 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/

相关文章:

c# - VS2015 代码覆盖率不适用于 ASP.NET Core 1.0(以前称为 ASP.NET 5)中的测试

c# - 使用 struct 强制验证内置类型的优缺点

android - 是否可以重用部分 AndroidManifest.xml 文件?

DRY docker-compose

c++ - 在完美转发函数中公开参数类型,避免代码重复

ruby-on-rails - 在 Rails 中实例化对象时如何初始化属性?

javascript - 如何减去asp文本框值并将结果放入asp标签中

c# - SignalR - Multi-Tenancy 依赖注入(inject)

c# - ASP.Net 请求引发 502 Bad Gateway 或 TimeOut

ruby - 我怎样才能在我的井字游戏中干掉这段 Ruby 代码? (使用 1.times block !)