2

以下不编译。既然这不是匿名方法、lambda 表达式或查询表达式,为什么这是一个限制?(将文本作为参考 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;
        }
    }
4

1 回答 1

3

编译器消息不完整,还应提及本地函数。

修改诊断仍然会给我留下“为什么这是一个限制?”。

局部函数不能从外部范围引用类似 ref 的结构,因为不需要在本地调用局部函数。

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
}

你提到:

(将文本作为参考 ReadOnlySpan 工作正常。)

这是正确的,但这会改变方法的签名。如果编译器这样做,就不能再将本地函数作为委托类型传递。


如评论中所述:

本地函数的不同翻译是可能的,实际上允许这样做,它只会禁止将这样的本地函数分配给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# 的未来扩展,这实际上可能是一个好主意。但此时,它还没有被设计或实现。在允许这样做之前,需要考虑几个极端情况,例如当有多个本地函数在捕获中有一些重叠时。

于 2018-04-04T15:38:01.773 回答