【发布时间】:2010-05-20 18:30:02
【问题描述】:
我使用过 Java、C++、.Net。 (以该顺序)。当被问及面试中的按价值与按参考时,我在这个问题上总是做得很好……也许是因为没有人深入研究它。现在我知道我没有看到全貌。
我在看别人写的这段代码:
XmlDocument doc = new XmlDocument();
AppendX(doc); // Real name of the function is different
AppendY(doc); // ditto
当我看到这段代码时,我想:等一下,我不应该在doc 变量前面使用ref 吗(并相应地修改AppendX/Y?它按写的那样工作,但让我质疑我是否真正理解C#中的ref关键字。
当我更多地思考这个问题时,我想起了早期的 Java 时代(大学介绍语言)。我的一个朋友看了我写的一些代码,他有一个心理障碍——他一直问我哪些东西是通过引用传递的,什么时候通过值传递的。我无知的反应是这样的:老兄,Java 中只有一种 arg 传递,我忘记了它是哪一种 :)。冷静,不要想太多,直接写代码。
Java 仍然没有ref 是吗?然而,Java 黑客似乎很有生产力。无论如何,用 C++ 编码让我接触到了这整个通过引用的业务,现在我很困惑。
上面的例子中应该使用ref吗?
我猜当ref 应用于值类型时:原语、枚举、结构(此列表中还有其他内容吗?)它会产生很大的不同。而且......当应用于对象时,它不会因为它都是引用。如果事情这么简单,那么编译器为什么不将ref 关键字的使用限制为类型的子集。
当涉及到对象时,ref 是否用作评论之类的?好吧,我确实记得null 可能会出现问题,ref 对于在一个方法中初始化多个元素也很有用(因为你不能像在 Python 中那样简单地返回多个东西)。
谢谢。
【问题讨论】:
-
将
ref参数添加到方法是您应该仅在需要时使用的东西。您的默认想法应该是避免使用ref参数。如果它按书面方式工作,请不要添加ref。顺便说一句,人们通常可以避免使用 ref,因为以下两个 sn-ps 通常会给出相同的结果(给定foo的合理实现):foo(ref x);和x = foo(x);。就个人而言,当有选择时,我将以第二种方式实现 foo 。因此,Java 程序员可以在没有它的情况下生存也就不足为奇了。 -
@Brian,当您拥有
x = foo(x);时,您的x也可能是不可变的(如string)。现在......当一种方法需要“返回”几个变量并且最好一起计算它们,因为它们是相关的......那么你会想要使用 ref,还是不使用?答案是否会根据参数是否不可变而改变?我想会的。 -
如果需要返回多个变量,可以使用
ref来实现。另一种方法是返回一个包含您希望返回的所有内容的类的实例。这通常但并不总是更好。请注意,您也可以使用out参数代替ref。如果您希望返回多个变量但实际上不需要传递它们,out更好。例如,foo(out x);类似于foo(ref x);,但应与未初始化的 x 一起使用。
标签: c# pass-by-reference