我正在寻找一个清晰、简洁和准确的答案。

理想情况下作为实际答案,尽管欢迎链接到好的解释。

这也适用于 VB.Net,但关键字不同 - ByRefByVal.

有帮助吗?

解决方案

默认情况下(在 C# 中),将对象传递给函数实际上会传递对该对象的引用的副本。更改参数本身只会更改参数中的值,而不更改指定的变量。

void Test1(string param)
{
    param = "new value";
}

string s1 = "initial value";
Test1(s1);
// s1 == "initial value"

使用 out 或者 ref 传递对函数调用中指定变量的引用。值的任何变化 out 或者 ref 参数将被传递回调用者。

两个都 outref 除了一点点差异之外,行为完全相同: 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 指出,之间的区别 outref 仅由 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 关键字的参数将被视为 输出参数

但这确实是您可以给出的最基本的答案,因为它比此处所述的要复杂一些

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top