在 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.ValueType
和System.Enum
也是引用类型,但从它们逻辑派生的值类型和枚举却不是。 【参考方案6】:
除了基本数据类型之外,您不能通过值传递其他任何内容,Array 是基本数据类型的集合,还允许在集合上按值传递会创建多个集合副本,这会影响性能。
【讨论】:
结构不是“基本数据类型”,它们是按值传递的。以上是关于在 C# 中传递数组参数:为啥它是通过引用隐式传递的?的主要内容,如果未能解决你的问题,请参考以下文章
为啥向量被视为按值传递,即使它是通过 const 引用传递的?