Span<T> 不能是嵌套局部变量。为什么这是一个限制?
Span<T> can not be a nested local variable. Why is this a restriction?
以下不编译。既然这不是匿名方法、lambda 表达式或查询表达式,为什么这是一个限制? (将文本作为 ref ReadOnlySpan 工作正常。)
void TestNestedSpan()
{
var text = "Some text".AsReadOnlySpan();
var success = TryParseS();
bool TryParseS()
{
//Compile Error CS8175 Cannot use ref local 'text' inside
// an anonymous method, lambda expression, or query expression
if (text.Length < 1 || text[0] != 'S')
return false;
text = text.Slice(1);
return true;
}
}
编译器消息不完整,还应提及局部函数。
Amending the diagnostic would still leave me with 'why is this a restriction?'.
局部函数无法从外部作用域引用 ref-like 结构,因为不需要在局部调用局部函数。
Action a;
void f() {
var s = "Hello, world!\n".AsReadOnlySpan();
void g() {
foreach (var c in s)
Console.Write(c);
}
a = g;
}
void h() {
a(); //call a which is in fact the "local" method g in f
}
你提到:
(Passing text as ref ReadOnlySpan works fine.)
这是正确的,但这会更改方法的签名。如果编译器这样做,将不再可能将本地函数作为委托类型传递。
如评论中所述:
局部函数的不同翻译可能实际上允许这样做,它只是不允许将这样的局部函数分配给 Action
:
Action a;
ref struct S {
public ReadOnlySpan<char> s;
public void g() {
foreach (var c in s)
Console.Write(c);
}
}
void f() {
S s;
s.s = "Hello, world!\n".AsReadOnlySpan();
s.g(); // okay
a = s.g; // error
}
作为 C# 的未来扩展,这实际上可能是个好主意。不过此时,它还没有被设计或实施。在允许这样做之前,需要考虑几种极端情况,例如当有多个局部函数在捕获中有一些重叠时。
以下不编译。既然这不是匿名方法、lambda 表达式或查询表达式,为什么这是一个限制? (将文本作为 ref ReadOnlySpan 工作正常。)
void TestNestedSpan()
{
var text = "Some text".AsReadOnlySpan();
var success = TryParseS();
bool TryParseS()
{
//Compile Error CS8175 Cannot use ref local 'text' inside
// an anonymous method, lambda expression, or query expression
if (text.Length < 1 || text[0] != 'S')
return false;
text = text.Slice(1);
return true;
}
}
编译器消息不完整,还应提及局部函数。
Amending the diagnostic would still leave me with 'why is this a restriction?'.
局部函数无法从外部作用域引用 ref-like 结构,因为不需要在局部调用局部函数。
Action a;
void f() {
var s = "Hello, world!\n".AsReadOnlySpan();
void g() {
foreach (var c in s)
Console.Write(c);
}
a = g;
}
void h() {
a(); //call a which is in fact the "local" method g in f
}
你提到:
(Passing text as ref ReadOnlySpan works fine.)
这是正确的,但这会更改方法的签名。如果编译器这样做,将不再可能将本地函数作为委托类型传递。
如评论中所述:
局部函数的不同翻译可能实际上允许这样做,它只是不允许将这样的局部函数分配给 Action
:
Action a;
ref struct S {
public ReadOnlySpan<char> s;
public void g() {
foreach (var c in s)
Console.Write(c);
}
}
void f() {
S s;
s.s = "Hello, world!\n".AsReadOnlySpan();
s.g(); // okay
a = s.g; // error
}
作为 C# 的未来扩展,这实际上可能是个好主意。不过此时,它还没有被设计或实施。在允许这样做之前,需要考虑几种极端情况,例如当有多个局部函数在捕获中有一些重叠时。