我正在寻找一个清晰,简洁和准确的答案.
理想情况下,作为实际答案,虽然欢迎链接到良好的解释.
这也适用于VB.Net,但关键字是不同的 - ByRef
和ByVal
.
默认情况下(在C#中),将对象传递给函数实际上会将引用的副本传递给该对象.更改参数本身只会更改参数中的值,而不会更改指定的变量.
void Test1(string param) { param = "new value"; } string s1 = "initial value"; Test1(s1); // s1 == "initial value"
使用out
或ref
传递对函数调用中指定的变量的引用.到的值的任何变化out
或ref
参数将被传递回给调用者.
双方out
并ref
表现相同,除了一个细微的差别:ref
需要参数调用之前被初始化,而out
参数可以未初始化.通过扩展,ref
保证参数在方法开始时初始化,而out
参数被视为未初始化.
void Test2(ref string param) { param = "new value"; } void Test3(out string param) { // Use of param here will not compile param = "another value"; } string s2 = "initial value"; string s3; Test2(ref s2); // s2 == "new value" // Test2(ref s3); // Passing ref s3 will not compile Test3(out s2); // s2 == "another value" Test3(out s3); // s3 == "another value"
编辑:作为DP指出,之间的差异out
,并ref
仅由C#编译器执行的,而不是由CLR.据我所知,VB没有相应的out
和仅实现ref
(as ByRef
),匹配CLR的支持.
关于ref与out的另一个注意事项:两者之间的区别由C#编译器强制执行.CLR不区分out和ref.这意味着您不能有两个方法,其签名只有out或ref
void foo(int value) {} // Only one of the following would be allowed // valid to overload with ref void foo(ref int value) {} // OR with out void foo(out int value) {}