重复:What is the purpose of the “out” keyword at the caller?
为什么我需要在声明和呼叫中使用'ref'关键字。
void foo(ref int i)
{
}
例如,考虑以上功能。如果我将其称为没有ref关键字
foo(k);
它会给我错误:
参数'1'必须与。一起传递 'ref'关键字
为什么仅仅在方法签名中指定不够?
答案 0 :(得分:12)
这是因为ref
表示该参数应该通过引用传入。它类似于C ++中的指针
例如;
void CalFoo()
{
var i=10;
foo(ref i); //i=11
}
void foo(ref int i)
{
i++;
}
但
void CalFoo()
{
var i=10;
foo(i); //i=10
}
void foo(int i)
{
i++;
}
我认为您可以在一个单独的课程中同时拥有foo(ref int)
和foo(int)
。所以,如果你没有指定ref
..编译器如何知道要调用哪一个?
答案 1 :(得分:9)
它增强了可读性/可理解性:当你查看方法调用时,你知道ref值可能会改变。
答案 2 :(得分:4)
(如上所述,这是this question的欺骗。)
首先,它被用作方法重载的一部分:
public void Foo(string x) { ... }
public void Foo(ref string x) { ... }
...
string x = "";
Foo(x); // Which should be used if you didn't have to specify ref?
现在一个答案可能就是禁止那种超载...但我认为C#在调用者身上需要这个作为文档是一件好事:
ref
(或out
)请注意,C#4允许对COM方法隐式使用ref
,因为有很多ref
个参数不会真的具有ref
行为(或者至少,他们没有利用它)。在这种情况下,编译器引入了一个新的局部变量,以便从调用者的角度来看,的参数是通过值传递的:
ComMethod(x);
转换为:
MyType tmp = x;
ComMethod (ref tmp);
这是COM方法的一个很好的折衷方案,但我很高兴普通托管代码不是这样。
答案 3 :(得分:3)
由于方法和调用者可能彼此“远离”(不同的程序集,您甚至可能没有包含该方法的源的源),因此必须明确指出并明确地帮助使目标明确。所以这对用户来说是有用的,这样他们才能真正知道他们做了什么,而不是技术上的必需品。
答案 4 :(得分:3)
尽管ref
大部分时间都可以从方法签名中推断出来,但由于它可以在完全调用方法之后改变代码的行为,因此它总是必须的。考虑:
string hello = "world";
MyMethod(ref hello);
Console.WriteLine(hello);
如果ref
关键字没有出现在那里,您总会希望代码打印出“世界”,而实际上,它可以打印任何内容。
答案 5 :(得分:1)
我也听过(或者在某个地方读过 - 我是在接受语言设计师的采访时),原因(就像C#中的许多其他“功能”一样)是提醒程序员他要调用的功能。通过引用使用参数。