Tre*_*ent 7 c# pass-by-reference
也许这对我来说有点天真,但我似乎无法找到/想到"通过引用传递"的体面用例.更改不可变字符串(正如其他一些Q/As所提到的)通常是可以避免的,返回多个变量通常可以通过返回元组,列表,数组等来更好地处理.
在我看来,MSDN上的例子很糟糕; 我只是在Square方法中返回一个值,而不是将其声明为void.
在我看来,它似乎是C#的一个遗留部分,而不是它的一个组成部分.有人比我更聪明可以尝试解释为什么它仍然存在和/或一些实际可行的实际用例(即几乎在每种情况下都可以避免更改不可变字符串).
PS:我跟进了@KallDrexx和@newacct的一些评论.我现在看到他们是对的,我错了:我的回答有点误导.优秀的文章"Java是价值传递,该死!" 作者:Scott Stanchfield(特定于Java,但仍然与C#最相关)终于让我信服了.
我将暂时删除我的答案的误导性内容,但可能会在以后删除它们.
通过引用传递不只是使用ref或out参数.更重要的是,所有引用类型都通过引用传递(因此它们的名称),尽管这是透明的.
以下是三个用于传递引用的常见用例:
struct传递它们时防止复制大s.想象一下,你有一个的byte[]表示二进制大对象(BLOB)数组,可能是struct包含大量字段的某种类型的大小值的几兆字节.该类型的值可能会占用大量内存.现在您要将此值传递给某个方法.你真的想通过它传递它,即创建一个临时副本吗?
您可以通过reference 传递大型结构来避免不必要的复制.
(对我们来说幸运的是,数组如byte[]引用类型,因此数组的内容已经通过refence传递.)
通常建议(例如在Microsoft的框架设计指南中)具有值类型语义的类型如果超过一定大小(32字节)则应实现为引用类型,因此该用例不应非常频繁.
可变性.如果您希望某个方法能够改变struct传递给它的值,并且您希望调用者观察该对象的版本的变异,那么您需要通过引用(ref)传递.如果值通过值传递给方法,则它会收到一个副本; 改变副本将使原始对象保持不变.
在上面链接的框架设计指南文章中也提到了这一点.
请注意针对可变值类型的广泛推荐(参见例如"为什么可变结构是邪恶的?").您应该很少使用ref或out参数与值类型一起使用.
本回答中提到的COM互操作通常需要您声明ref和out参数.