子引用Ref时需要关键字Ref?

时间:2018-08-20 10:02:13

标签: c# ref

我在这个question

处发现了这种方法
public static void RemoveAt<T>(ref T[] arr, int index)
{
    for (int a = index; a < arr.Length - 1; a++)
    {
        arr[a] = arr[a + 1];
    }
    Array.Resize(ref arr, arr.Length - 1);
}

现在,我想知道如果在嵌套方法中使用ref是必需的吗?这样的方法也可以:

public static void RemoveAt<T>(T[] arr, int index) //ref removed

具有相同的功能?我已经对其进行了测试,并且可以正常工作-但这意味着您可以更改引用而无需通过Ref关键字。您只是可以通过子方法来做到这一点。

2 个答案:

答案 0 :(得分:0)

  

但是这意味着您可以更改参考而无需传递参考关键字。您只是可以通过子方法来完成

那不是事实。尽管您可以在RemoveAt方法中的内部中更改引用,但是该更改不会影响传递给它的引用。您只需丢弃新的(调整大小的)实例即可。当您想更改引用以指向其他实例时,您的方法应使用ref关键字。

在其他关键字中,您的第二个代码也可以这样写:

public static void RemoveAt<T>(arr, int index)
{
    for (int a = index; a < arr.Length - 1; a++)
    {
        arr[a] = arr[a + 1];
    }
    var reference = arr;
    Array.Resize(ref reference, arr.Length - 1);
}

虽然reference在调用Array.Resize之后会发生变化,但是arr将保持不变。他们引用了完全不同的实例。

答案 1 :(得分:0)

功能将不同。 Resize可以将引用更改为arr,因此在第一种情况下,您将更改调用方的外部引用,而没有ref的情况下,您将仅更改本地方法引用

带参考:

var extArr = new object[100];

RemoveAt(ref extArr, 10); // The arr variable in this method is now the exact same physical
                          // variable as extArr.

// extArr is now a completely valid reference to the resized array, business as usual.

没有:

var extArr = new object[100];

RemoveAt(extArr , 10); // The copy of the reference (arr) is updated in this method 
                       //internally, but the local variable extArr is only copied and not modified

// extArr is now a reference to the old, not-resized array. 
// Note that the element is still "removed", overwritten in the for loop,
// but the resized copy of the array is lost and has no references to it.