为什么我可以引用 return 仅存在于方法内部的数组项?

Why can I ref return an item of an array that only exists inside the method?

我正在试用 C#7 的新参考 return。

我能够编译和构建这个:

        public ref string MisUseRefReturn(int index)
    {
        string[] array = { "a", "b", "c", "d" };
        return ref array[index]; //array[2] gets out of scope when this method returns!
    }

根据 MSDN:return 值不能是 return 方法中的局部变量;它必须有一个在 return 方法之外的作用域。它可以是 class 的实例或静态字段,也可以是传递给方法的参数。尝试 return 局部变量会生成编译器错误 CS8168,"Cannot return local 'obj' by reference because it is not a ref local."

那么为什么要编译呢?当我执行此方法时,returned 引用显示正确的字符串。

将数组元素视为数组的实例字段。假设您的数组是:

public class FourElementStringArray
{
    public string element0;
    public string element1;
    public string element2;
    public string element3;
}

那么你的代码相当于:

public ref string MisUseRefReturn(int index)
{
    var array = new FourElementStringArray
    {
        element0 = "a",
        element1 = "b",
        element2 = "c",
        element3 = "d"
    };
    // TODO: do this dynamically based on index
    return ref array.element2;
}

这与您引用的文档一致:

It can be an instance or static field of a class, or it can be an argument passed to the method.

这个有用吗?不是特别。危险吗?编号

后半部分是重点。使用常规数组,如果调用者分配了一个新值,那很好——它正在替换堆上数组的一个元素。当数组元素引用存在时,数组不能被垃圾回收;基本没问题

编译器规则试图阻止的是使用返回的对堆栈中某处的引用,然后返回的方法将其弹出。数组本身不在栈上,所以这里没有问题。

查看说明here:

Returning a local int variable instead of an array is not possible. int is a value type, and thus the variable gets out of scope at the end of the method, and thus a reference to it cannot be returned. That’s different with an array. An array is a reference type, and the array is allocated on the heap. An int within the array can be returned with the ref keyword.

您不能直接 return 整数值,因为它是值类型。数组元素可以被 returned 因为它是引用类型。 MSDN 的说法是正确的。

... of an array that only exists inside the method

returned 引用在方法调用之后保留数组。