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

Posted

技术标签:

【中文标题】C# 传递参数(值或引用)?【英文标题】:C# passing parameter (value or reference)? 【发布时间】:2012-06-08 12:17:55 【问题描述】:

有人告诉我,当您将对象传递给方法时, 它是“按值”传递的。我做了一个小测试来检查它:

Point p = new Point(1, 1);
Circle c = new Circle(p);
p.x = 999;
Console.WriteLine(c.p.x);

上面的代码打印“999”,但我认为对象被复制到方法中 有人告诉我,如果您不使用“ref”(或“out”)该方法获取值 的对象。

有人可以告诉我吗? 谢谢, 插座

【问题讨论】:

见Parameter Passing in C# 在这种情况下它是一个构造函数,它有什么不同吗? Point 和 Circle 是什么类型,能否提供一个声明? 这里有两个完全不相关的概念被混为一谈——“通过引用传递”和“引用类型”。这些在很大程度上是不相关的,但我担心你会混淆它们。 【参考方案1】:

C# 是按值传递的——引用值在正常情况下传递,也就是说。 (这意味着它是对同一对象的新引用)

【讨论】:

【参考方案2】:

Point 是结构体,所以按值传递。

【讨论】:

【参考方案3】:

假设Point 被声明为类,而不是复制p 本身,则复制p引用。所以它仍然是按值传递。您传递引用的值。

当说Point p = new Point(1, 1);(如果point是引用类型)时,人们可能会认为它是一个包含Point的变量,但实际上它是一个包含对存储在某处的Point的引用的变量别的。

【讨论】:

@Botz3000 - 你能举一个“通过引用”的例子吗? @Saul 参数可以使用refout 关键字通过引用传递。不过很少需要。 @Botz3000 - 好的。 Circle c = new Circle(out p); 会有什么不同? @Saul 您可以修改变量 p 的值。在这种情况下,这意味着,在 Circle 构造函数中,您可以为 p 分配一个全新的对象。如果没有 out 修饰符,原始变量 p 仍将指向同一个对象。【参考方案4】:

在.NET中,有两类类型,引用类型值类型

结构是值类型,类是引用类型

一般的不同是引用类型存在于堆上,而一个值类型存在于内联,也就是说,无论它是你的变量或字段被定义的地方。

包含值类型的变量包含整个值类型值。对于结构体,这意味着变量包含整个结构体及其所有字段。

一个包含引用类型的变量包含一个指针,或一个引用到内存中实际值所在的其他地方。

这有一个好处,首先:

值类型总是包含一个值 引用类型可以包含一个null-引用,这意味着它们现在根本不引用任何东西

在内部,引用类型被实现为指针,知道这一点,知道变量赋值是如何工作的,还有其他行为模式:

值类型变量的内容复制到另一个变量中,将整个内容复制到新变量中,使两者不同。换句话说,在复制之后,对其中一个的更改不会影响另一个 将引用类型变量的内容复制到另一个变量中,复制该引用,这意味着您现在有两个引用到相同的其他地方存储实际数据.换句话说,在复制之后,更改一个引用中的数据似乎也会影响另一个引用,但这只是因为您实际上只是在两个地方查看相同的数据

当您声明变量或字段时,这两种类型的区别如下:

变量:值类型存在于栈中,引用类型存在于栈中,作为指向实际内存所在的堆内存某处的指针 class/struct-field:值类型存在于类中,引用类型存在于类中,作为指向实际内存所在的堆内存中某处的指针。

请参阅MSDN,此tutorial 类似于您的圆/点/轴示例。

【讨论】:

以上是关于C# 传递参数(值或引用)?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 是不是通过值或引用传递对象?

C#在方法调用中,参数按值传递与按引用传递的区别是啥?

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

C#中的引用传递值传递。

如何通过值或常量引用传递 std::string_view

c# 值传递 引用传递