c# - 从方法 C# 返回数组

标签 c# methods reference heap-memory pass-by-reference

我一直在想,为什么我的方法不是修改数组,当我将它用作参数并使它等于另一个具有不同值的数组时,在方法内部? 我只是在更改引用地址吗?

    static void Main()
    {
        string[] array = { "yes", "no", "maybe" };
        TestO(array); // Still "yes", "no", "maybe"
    }

    static void TestO(string[] array)
    {
        string[] secondArray = new string[array.Length]; 
        secondArray[0] = "1";
        secondArray[1] = "2";
        secondArray[2] = "3";
        array = secondArray; 
    }

我的猜测:我没有在 Main() 中修改数组,因为在 Test0() 方法中执行 array = secondArray; 时, 我只是将array的引用地址改成了secondArray

如果我的猜测不对,我的问题是,为什么它没有被修改?

(我知道我可以将 Test0() 修改为 string[] 返回方法并返回修改后的 secondArray 并将其传递到 Main()) 中的 array

另一个问题是: 如果我使用 string[] 返回方法,并声明如下:

        static void Main()
    {
        string[] array = { "yes", "no", "maybe" };
        array = TestO(array); 
    }

    static string[] TestO(string[] methodArray)
    {
        string[] secondArray = new string[methodArray.Length];
        secondArray[0] = "1";
        secondArray[1] = "2";
        secondArray[2] = "3";
        return secondArray; 
    }

array = TestO(array); 我只是将 secondArray[] 的引用地址传递给 array[] 还是我只传递值吗? (很可能是引用地址,但我想确定是否弄错了)

最佳答案

I just changed the reference address of array to secondArray. If my guess is not right, my question is, why exactly is it not getting modified?

我认为您倾向于理解内存中有两个对一个数据的引用(没有两个数据);你有一个指向数据的变量array。您调用一个方法,另一个方法,复制引用建立到相同的数据。您创建了一个新对象,然后将复制的引用指向新对象,将原始引用指向原始数据,然后您丢弃了复制引用和新数据。您又回到了完全相同的情况开始于。

从图形上看,一行一行,它可能看起来像(我将你的方法参数重命名为 arrayX 所以区别很明显):

enter image description here

如果用 ref 修饰参数并用 ref 调用它,则没有副本,因此被调用的方法可以修改原始引用并将其指向其他地方:

enter image description here

请注意,在这些情况的任一种中,都完全有可能修改数组的内容。正在做:

arrayX[0] = "New data";

..将在任一情况下生效并且打印array[0] 将显示“新数据”。修改箭头末端的数据时,起点是原始引用还是副本并不重要。这纯粹是关于方法是否有权将传递给它的原始引用指向另一个对象

通常我们这样做。我们采用您的第二个代码块的样式 - 返回数据。将其视为粗鲁可能会有所帮助 - 想象一下您的 friend 说他会在您度假时照看您的植物;你把 key 给了你的 friend 。他把你的植物换成他更喜欢的另一种植物;你很沮丧,因为你拥有那株植物十年了..

使用ref 或相关的“覆盖引用的能力”- out 的理由很少。不要将它用于“我想从我的方法中返回多个东西”——在面向对象的世界中,我们总是可以返回一个代表两项数据的东西。我们不需要“返回两个东西”;我们可以返回一个里面有两个东西的东西......

//don't:
void GetPerson(ref string name, ref int age)

//consider a class:
Person GetPerson()
  return new Person(){ Name = ..., Age = ...}

//or a Tuple
(string Name, int Age) GetPerson

让调用方法选择是否应该覆盖它自己的变量,而不是让一些“第三方”把地毯从它脚下拉下来

关于c# - 从方法 C# 返回数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71196858/

相关文章:

c++ - 为什么非常量引用不能绑定(bind)到临时对象?

c# - 无法在 SQLite Net Platform WinRT 中加载 DLL 'sqlite3'

c# - Xamarin 警报失败

python - 如何确定实例方法对应的类?

java - 如何从同一个类中的另一个方法调用一个方法(java)

c++ - 在 C++ 中 throw e for refer 时局部 var destroy?

c++ - 为什么要使外部变量成为引用?

c# - 如何在单击按钮时动态更改组框?

c# - 泛型类的隐式转换仅限于某些类型

java - 如何使用 HashMap 解读单词列表?