【问题标题】:Array parameter passing in C#: why is it implicitly by reference?在 C# 中传递数组参数:为什么它是通过引用隐式传递的?
【发布时间】:2011-04-05 23:40:33
【问题描述】:

假设以下代码,没有任何 ref 关键字,显然不会替换传递的变量,因为它是作为值传递的。

class ProgramInt
{
    public static void Test(int i) // Pass by Value
    {
        i = 2; // Working on copy.
    }

    static void Main(string[] args)
    {
        int i = 1;
        ProgramInt.Test(i);
        Console.WriteLine(i);
        Console.Read();

        // Output: 1
    }
}

现在要让该功能按预期工作,可以像往常一样添加 ref 关键字:

class ProgramIntRef
{
    public static void Test(ref int i) // Pass by Reference
    {
        i = 2; // Working on reference.
    }

    static void Main(string[] args)
    {
        int i = 1;
        ProgramInt.Test(ref i);
        Console.WriteLine(i);
        Console.Read();

        // Output: 2
    }
}

现在我很困惑为什么数组成员在传入函数时是通过引用隐式传递的。数组不是值类型吗?

class ProgramIntArray
{
    public static void Test(int[] ia) // Pass by Value
    {
        ia[0] = 2; // Working as reference?
    }

    static void Main(string[] args)
    {
        int[] test = new int[] { 1 };
        ProgramIntArray.Test(test);
        Console.WriteLine(test[0]);
        Console.Read();

        // Output: 2
    }
}

【问题讨论】:

    标签: c# arrays pass-by-reference parameter-passing pass-by-value


    【解决方案1】:

    不,数组是类,这意味着它们是引用类型。

    【讨论】:

    • 一般情况下,你可以在任何类型上按 F12 来查找。如果声明说“类”,它是一个引用类型;如果它说“结构”,它是一个值类型。不幸的是,它不允许你用数组来做这件事,这是一种耻辱。所以你只需要记住数组是引用类型,即使它是一个值类型的数组。
    • 补充 Timwi 所说的,F12 是 Visual Studio 的热键。
    【解决方案2】:

    数组不是通过引用传递的。对数组的引用按值传递。如果需要更改传入的数组变量指向的 WHAT 数组(例如更改数组的大小),则必须通过引用传递变量。

    【讨论】:

      【解决方案3】:

      记住这一点的好方法是:

      • "ref" 使 别名 成为 变量
      • 数组是一个变量的集合;每个元素都是一个变量。

      当你正常传递一个数组时,你传递的是一个变量集合。集合中的变量不会改变。

      当您使用“ref”传递一个数组时,您为包含该数组的变量提供了一个新名称

      当您通常传递一个数组元素时,您传递的是变量中的值

      当您通过“ref”传递一个数组元素 - 一个变量时,您为该变量提供了一个新名称

      有意义吗?

      【讨论】:

      • 我个人喜欢上面所说的地址,但大多数人仍然不明白。这是我用狗来比喻的一种方式,但它似乎真的很蹩脚:stackoverflow.com/questions/3366650/…
      • 就我个人而言,我不喜欢“给一个新名字”这样的措辞。出于某种原因,它只是不适合我。但不知道新手会怎么看。
      【解决方案4】:

      您能想象按值传递一个包含 200 万个元素的数组吗?现在想象元素类型是decimal。您将需要复制大约 240MB 30.5175781MB 的数据。

      【讨论】:

        【解决方案5】:

        the MSDN reference所示,数组是对象(System.Array是所有数组的抽象基类型),对象是通过引用传递的。

        【讨论】:

        • 我本来要提到System.Array,但后来我想起System.ValueTypeSystem.Enum 也是引用类型,但从它们逻辑派生的值类型和枚举却不是。
        【解决方案6】:

        除了基本数据类型之外,您不能通过值传递其他任何内容,Array 是基本数据类型的集合,还允许在集合上按值传递会创建多个集合副本,这会影响性能。

        【讨论】:

        • 结构不是“基本数据类型”,它们是按值传递的。
        猜你喜欢
        • 2014-07-26
        • 1970-01-01
        • 1970-01-01
        • 2020-03-26
        • 2012-06-24
        • 2011-12-15
        • 2016-12-22
        • 2020-07-30
        • 2012-04-17
        相关资源
        最近更新 更多