ref、val 和 out 对方法参数的含义是啥?
Posted
技术标签:
【中文标题】ref、val 和 out 对方法参数的含义是啥?【英文标题】:What do ref, val and out mean on method parameters?ref、val 和 out 对方法参数的含义是什么? 【发布时间】:2010-09-05 23:56:54 【问题描述】:我正在寻找一个清晰、简洁和准确的答案。
理想情况下作为实际答案,尽管欢迎提供良好解释的链接。
这也适用于 VB.Net,但关键字不同 - ByRef
和 ByVal
。
【问题讨论】:
【参考方案1】:关于 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)
【讨论】:
【参考方案2】:默认情况下(在 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 的支持相匹配。
【讨论】:
“对该对象的引用的副本”或“对该对象的副本的引用”?【参考方案3】:我自己在 *** 上的一个问题也处理了这个话题。 它以不同类型的语言处理"pass by reference" and "pass by value",c# is included,所以也许你也可以在那里找到一些额外的信息。
基本上归结为:
ref:带有ref关键字的参数将通过引用传递 out:带有out关键字的参数将被视为输出参数但这确实是你能给出的最基本的答案,因为它比这里所说的要复杂一些
【讨论】:
【参考方案4】: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
【讨论】:
以上是关于ref、val 和 out 对方法参数的含义是啥?的主要内容,如果未能解决你的问题,请参考以下文章