Action<Span<byte>> 抛出编译错误,但 delegate void TestMeDelegate(Span<byte> data) 不会

Action<Span<byte>> throws compilation error, but delegate void TestMeDelegate(Span<byte> data) doesn't

检查以下代码。

class Program
{
    delegate void TestMeDelegate(Span<byte> data);

    static void Main(string[] args)
    {
        TestMeDelegate testMeDelegate = TestMe;
        Action<Span<byte>> testMeAction = TestMe;
    }

    static void TestMe(Span<byte> data)
    {
    }
}

使用 testMeDelegate 的行有效,但使用 testMeAction 的行 抛出

The type 'Span<byte>' may not be used as a type argument

我是 targeting.net 4.7.2,System.Memory nuget 版本 4.5.1

Langversion 设置为 C# 最新的次要版本(latest)应该是 7.3

问题:

这仅仅是一个编译器错误吗?

这个场景下Action和delegate有什么区别?

与错误描述的完全一致。

Span<T>类型是一个ref struct,意味着它的存储位置只能在栈上(所以不能在堆上)。如果不能保证,编译器将输出诊断结果。

问题是编译器无法用泛型确定这一点。尽管编译器可以检测到某些情况(例如您的情况),但编译器团队已决定根本不允许 ref struct 类型用作泛型类型。

我不知道他们没有正确检查通用类型的确切原因,但我能想到的是:

  • 会大大增加编译器的复杂性
  • 对于类型不能用作给定类型的泛型参数的情况,即使可能的话,也很难生成正确的诊断消息。