C# 参数传递:值传递与引用传递的深入探讨
C# 中,值传递和引用传递是程序员必须掌握的基本概念。虽然通常认为非原始类型是引用传递,但对于某些非原始对象(例如 System.Drawing.Image)来说,情况并非总是如此。
System.Drawing.Image 对象的特殊性
将 System.Drawing.Image 对象传递给方法并向其中加载图像时,我们通常期望原始对象在返回后反映这些更改。然而,对于 System.Drawing.Image 并非如此。在被调用方法中所做的更改不会传播回调用方,从而导致混淆。
“引用传递”的真相
这种误解源于对引用传递含义的误解。在 C# 中,对象本身不会被传递。相反,它们的值作为初始参数值按值传递。对于引用类型,这些值是对对象本身的引用。因此,在被调用方法中对对象本身所做的任何更改都将对调用方可见。
但是,重要的是要注意,参数本身的值(即对对象的引用)不是按引用传递的。这意味着如果参数被分配一个新值,引用一个不同的对象,则调用方将看不到此更改。
解决方案:显式引用传递
为了确保对参数本身的更改对调用方可见,必须使用显式引用传递。无论参数是值类型还是引用类型,这都可以通过 out
或 ref
修饰符来实现。
通过使用这些修饰符,参数实际上是按引用传递的,并且在方法中对其所做的更改将反映在调用方中。
示例
为了说明这个概念,请考虑以下示例:
<code class="language-csharp">public void Foo(Image image) { // 此更改对调用方不可见。 image = Image.FromStream(...); } public void Foo(ref Image image) { // 此更改对调用方可见。 image = Image.FromStream(...); } public void Foo(Image image) { // 此更改对调用方可见。 image.RotateFlip(...); }</code>
在第一个示例中,参数按值传递,对参数本身的更改对调用方不可见。在第二个示例中,使用 ref
修饰符显式地按引用传递参数,对参数本身的更改是可见的。在第三个示例中,参数按引用传递,但对对象本身的更改是可见的,因为参数值是对对象的引用。
结论
C# 中的引用传递是一个细微的概念,其行为并不总是像我们直觉上期望的那样。理解按引用传递对象与按引用传递值之间的区别对于编写按预期方式运行的代码至关重要。
以上是C#参数传递如何真正起作用:值与参考?的详细内容。更多信息请关注PHP中文网其他相关文章!