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

百般思念 提交于 2019-12-21 10:18:07

问题


I was trying out the new ref returns of C#7.

I am able to compile and build this:

        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!
    }

According to MSDN: The return value cannot be a local variable in the method that returns it; it must have a scope that is outside the method that returns it. It can be an instance or static field of a class, or it can be an argument passed to the method. Attempting to return a local variable generates compiler error CS8168, "Cannot return local 'obj' by reference because it is not a ref local."

So why does this compile? When I execute this method, the returned reference shows the correct string.


回答1:


See the description 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.

You could not return an integer value directly as it is a value type. An array element can be returned because it is a reference type. The MSDN statement is correct.

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

The returned reference persists the array beyond the method call.




回答2:


Think of the array element as if it were an instance field of the array. Imagine your array were:

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

Then your code is equivalent to:

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;
}

That abides by the piece of documentation you quoted:

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

Is this useful? Not particularly. Is it dangerous? No.

The latter part is the important point. Using the regular array, if the caller assigns a new value, that's fine - it's replacing an element of an array, on the heap. The array can't be garbage collected while the array element reference exists; all is basically okay.

What the compiler rule is trying to prevent is the use of a returned reference to somewhere on the stack which has then been popped by the method returning. The array itself isn't on the stack, so there's no problem here.



来源:https://stackoverflow.com/questions/48075085/why-can-i-ref-return-an-item-of-an-array-that-only-exists-inside-the-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!