默认情况下,数组或列表是通过c#中的引用传递的吗?


84

有吗 还是为了加快我的程序,我应该通过引用传递它们?


35
为了加快程序运行速度,您应该(1)设定有意义的目标,(2)测试以查看您是否达到了目标,(3)如果尚未达到目标,请使用性能分析工具查找最慢的东西,以及(4 )优化最慢的东西。
Eric Lippert


3
@EricLippert您的评论回答了OP的实际问题远胜过任何已发布的答案。每个人都对“按值传递参考”技术如此分心,以至于他们完全忽略了有关性能优化的真正问题。不幸的是,OP传达了他的需求相当差,其他答案至少将对Google人群有所帮助。
丹·贝查德

“其他答案至少会帮助Google人群”-他们会的!:)
miki

Answers:


208

引用按值传递。

.NET中的数组是堆上的对象,因此您有一个引用。该引用按值传递,这意味着调用者将可以看到对数组内容的更改,但是重新分配数组不会:

void Foo(int[] data) {
    data[0] = 1; // caller sees this
}
void Bar(int[] data) {
    data = new int[20]; // but not this
}

如果添加ref修饰符,则引用通过引用传递-调用者将在上面看到任一更改。


28
答案是正确的,但我有些讨厌“标准是通过价值传递”的人。这使问题感到困惑。是的,引用(内存地址)是按值传递的,但这不是问题。
WernerVA

9
@WernerVA我很感兴趣,你是怎么想的,你会不同的是遗体表达出来纠正明确的
马克·Gravell

2
我不会表达出不同,只是可能会有更多细节。
WernerVA 2015年

这不能回答问题的速度部分。对您来说显而易见的是,与其他数百种昂贵得多的操作相比,优化参考副本将完全可以忽略不计,但是OP确实对此提出了具体要求。
丹·贝查德

7
@Dan速度部分固有地链接到“如果数组通过值传递-表示数组内容的副本-表示所有内存的分配和副本”。由于是通过的参考,因此无需回答性能问题-问题的那一部分将被模拟并自动回答。除了现在,它还在评论中得到明确的回答...
马克·格雷韦尔

9

它们通过值传递(所有参数既不是ref也不是out),但是该值对对象的引用,因此它们通过引用有效地传递。


0

是的,默认情况下在C#中通过引用传递它们。除了值类型,C#中的所有对象都是。更确切地说,它们是“按值引用”传递的;也就是说,您在方法中看到的变量的值是对传递的原始对象的引用。这是一个很小的语义要点,但有时可能很重要。


9
引用按值传递;这与“它们通过引用传递”非常不同。
马克·格雷韦尔

1
这与事实完全相反。引用约翰·斯凯特(John Skeet)的文章:“默认情况下,所有参数都在C#中按值传递。仅当您明确包含out或ref修饰符时,参数才通过引用传递。但是,您需要知道当参数的类型时是引用类型,您传递的是引用而不是实际的对象”。值传递的只是引用(内存地址)。
alexlomba87
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.