【发布时间】:2014-05-27 07:17:03
【问题描述】:
在 C# 的传递引用和传递值概念的上下文中,我有一个关于深复制和浅复制的一般性问题:
在 C# 中,需要显式创建接受指针/引用的方法才能将其传递给方法。但是,至少作为参数传递给方法/构造函数的对象的行为与其他对象不同。如果没有按照此处所述进行额外克隆,它们似乎总是通过引用传递:http://zetcode.com/lang/csharp/oopii/。
为什么对象会自动通过引用传递? 在这些情况下,强制克隆过程而不是像 int、double、boolean 等那样处理对象有什么特别的好处吗?
这是说明我的意思的代码示例:
using System;
public class Entry
{
public class MyColor
{
public int r = 0;
public int g = 0;
public int b = 0;
public double a = 1;
public MyColor (int r, int g, int b, double a)
{
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
}
public class A
{
public int id;
public MyColor color;
public MyColor hiddenColor;
public A (int id, MyColor color)
{
this.id = id;
this.color = color;
}
}
static void Main(string[] args)
{
int id = 0;
MyColor col = new MyColor(1, 2, 3, 1.0);
A a1 = new A(id, col);
A a2 = new A(id, col);
a1.hiddenColor = col;
a2.hiddenColor = col;
a1.id = -999;
id = 1;
col.a = 0;
Console.WriteLine(a1.id);
Console.WriteLine(a2.id);
Console.WriteLine(a1.color.a);
Console.WriteLine(a2.color.a);
Console.WriteLine(a1.hiddenColor.a);
Console.WriteLine(a2.hiddenColor.a);
}
}
这会导致:
-999
0
0
0
0
MyCol 的实例始终按引用传递,而其他参数按值传递。我必须在 MyColor 和 A 类中实现 ICloneable。另一方面,'ref'-statement 出现在 C# 中,它应该用于显式允许和执行 pass-by-reference。
欢迎提出建议!
【问题讨论】:
-
并非所有实例都自动通过引用传递。结构实例是按值传递的——看起来你的类应该是一个结构,因为它是一组颜色值。
-
@BoltClock,实际上所有类型都是按值传递的(包括引用类型),除非另有说明。对于引用类型,它只是意味着传递的值是一个引用,但它仍然是按值传递的:为参数分配一个新的引用不会影响调用者。
-
@BoltClock,我同意它一开始是令人困惑,但区别很重要,所以我认为最好准确地解释它;)
-
@ThomasLevesque 我同意这种区别很重要,但是关于它的迂腐主义有点愚蠢。对象不是按值传递的。相反,按值传递的是对对象的引用。说“一个对象是按值传递的,但值是对象以外的东西”是没有意义的。只要传递给函数的是对象的引用,声称“对象不是通过引用传递”是愚蠢的。
-
要真正了解发生了什么,您需要了解指针。对象引用只不过是一个指针。通过引用传递一个值会传递一个指向该值的指针。 C 语言是一门好学的语言,它迫使您考虑指针,并且几乎没有将机器抽象出来。这就是为什么它是一种快速的语言。还有一个危险的。
标签: c# clone pass-by-reference pass-by-value shallow-copy