You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# 11 ref参数逃逸规则疑问:ref int与Span<int>编译差异

为何以下C# 11代码无法编译?
// Example 1 - 编译失败
class C {
    public Span<int> M(ref int arg) {
        Span<int> span;
        span = new Span<int>(ref arg);
        return span;
    }
}

该代码产生两个编译错误:

error CS9077: 无法通过ref参数返回参数引用的'arg';它只能在return语句中返回。
error CS8347: 无法在此上下文中使用'Span.Span(ref int)'的结果,因为它可能会将参数'reference'引用的变量暴露到其声明范围之外。

我对此感到困惑:代码并未尝试通过ref参数返回arg,也不会将arg引用的变量暴露到其声明范围外。

对比之下,以下两段代码可成功编译:

// Example 2 - 编译成功
class C {
    public Span<int> M(ref int arg) {
        Span<int> span = new Span<int>(ref arg);
        return span;
    }
}
// Example 3 - 编译成功
class C {
    public Span<int> M(Span<int> arg) {
        Span<int> span;
        span = new Span<int>(ref arg[0]);
        return span;
    }
}

我的直觉是Span<int>内部持有int类型的ref字段,因此示例1和3的逃逸规则应该一致,但实际并非如此。

我用显式持有ref字段的ref struct做了类似实验:

ref struct S {
    public ref int X;
}

以下代码编译失败:

// Example 4 - 编译失败
class C {
    public S M(ref int arg) {
        S instance;
        instance.X = ref arg;
        return instance;
    }
}

错误信息为:

error CS9079: 无法将'arg' ref赋值给'X',因为'arg'只能通过return语句逃逸当前方法。

对比之下,以下两段代码可成功编译:

// Example 5 - 编译成功
class C {
    public S M(ref int arg) {
        S instance = new S() { X = ref arg };
        return instance;
    }
}
// Example 6 - 编译成功
class C {
    public S M(S arg) {
        S instance;
        instance.X = ref arg.X;
        return instance;
    }
}

特别地,若如示例4的错误信息所述,arg只能通过return语句逃逸当前方法,为何示例6中的arg.X不受此限制?

我尝试在C# 11低级结构体改进文档中寻找答案但未成功,且该文档存在多处矛盾。

内容的提问来源于Stack Exchange,提问作者Bartosz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:16:15