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
类型用作泛型类型。
我不知道他们没有正确检查通用类型的确切原因,但我能想到的是:
- 会大大增加编译器的复杂性
- 对于类型不能用作给定类型的泛型参数的情况,即使可能的话,也很难生成正确的诊断消息。
检查以下代码。
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
类型用作泛型类型。
我不知道他们没有正确检查通用类型的确切原因,但我能想到的是:
- 会大大增加编译器的复杂性
- 对于类型不能用作给定类型的泛型参数的情况,即使可能的话,也很难生成正确的诊断消息。