在 C# 中传递数组参数:为啥它是通过引用隐式传递的?

Posted

技术标签:

【中文标题】在 C# 中传递数组参数:为啥它是通过引用隐式传递的?【英文标题】: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
    

【问题讨论】:

【参考方案1】:

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

【讨论】:

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

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

【讨论】:

【参考方案3】:

记住这一点的好方法是:

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

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

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

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

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

有意义吗?

【讨论】:

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

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

【讨论】:

【参考方案5】:

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

【讨论】:

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

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

【讨论】:

结构不是“基本数据类型”,它们是按值传递的。

以上是关于在 C# 中传递数组参数:为啥它是通过引用隐式传递的?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过引用从 c# 到 c++ 传递字节数组

为啥向量被视为按值传递,即使它是通过 const 引用传递的?

C#中数组作为参数传递的问题

在c#中将引用数组作为参数传递[重复]

为啥 PHP 在一种情况下允许将文字传递给按引用传递的参数,而在其他情况下不允许?

C# 传递参数(值或引用)?