题
我正在寻找一个清晰、简洁和准确的答案。
理想情况下作为实际答案,尽管欢迎链接到好的解释。
这也适用于 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
(作为 ByRef
) 仅匹配 CLR 的支持。
其他提示
关于 ref 与 ref 的附加注释出去:两者之间的区别是由 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) {}
out
意味着该参数将由以下方法初始化:
int result; //not initialised
if( int.TryParse( "123", out result ) )
//result is now 123
else
//if TryParse failed result has still be
// initialised to its default value (0)
ref
将强制传递底层引用:
void ChangeMyClass1( MyClass input ) {
input.MyProperty = "changed by 1";
input = null;
//can't see input anymore ...
// I've only nulled my local scope's reference
}
void ChangeMyClass2( ref MyClass input ) {
input.MyProperty = "changed by 2";
input = null;
//the passed reference is now null too.
}
MyClass tester = new MyClass { MyProperty = "initial value" };
ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"
ChangeMyClass2( ref tester );
// now tester is null
我自己在 stackoverflow 上提出的问题之一也涉及这个主题。
它处理大约 “按引用传递”和“按值传递” 以不同类型的语言, 包含 c# 所以也许您还可以在那里找到一些额外的信息。
基本上可以归结为:
- 参考:带有 ref 关键字的参数将被传递 引用
- 出去:带有 out 关键字的参数将被视为 输出参数
但这确实是您可以给出的最基本的答案,因为它比此处所述的要复杂一些
不隶属于 StackOverflow