C# 为什么我需要在params前面加out或ref?

C# 为什么我需要在params前面加out或ref?,c#,C#,如果我调用的方法使用out或ref参数,为什么在调用该方法时需要将参数标记为out或ref?i、 e DateTime.TryParse(myDate, out dateLogged) 我原以为这是在运算符重载时减少歧义的方法,但如果我创建两种类似的方法: void DoStuff(int x, out int y) { y = x + 1; } void DoStuff(int x, ref int y) { y = x + 1; } 然后VisualStudio报告“无

如果我调用的方法使用out或ref参数,为什么在调用该方法时需要将参数标记为out或ref?i、 e

DateTime.TryParse(myDate, out dateLogged)
我原以为这是在运算符重载时减少歧义的方法,但如果我创建两种类似的方法:

void DoStuff(int x, out int y)
{
    y = x + 1;
}

void DoStuff(int x, ref int y)
{
    y = x + 1;
}
然后VisualStudio报告“无法定义重载方法'DoStuff',因为它只在ref和out上与另一个方法不同”,所以我无论如何也不能这样做

编辑:

经过进一步研究,如果有两个重载方法声明如下,则调用方法时似乎需要指定out或ref:

    void DoStuff(int x, out int y)

    void DoStuff(int x, int y)

你的案子可以被认为是一个黑客。它的目的是允许方法更改参数的值

例如:

void someMethod(ref i)
{
 i = 1;
}


int i = 0;
someMethod(ref i); //i now becomes 1, without the ref it would stay 0.

裁判和出局其实是一回事。区别在于out关键字使编译器在从方法返回之前检查变量是否已赋值

编辑


抱歉,误解了这个问题,我以为你在问为什么c#不允许你有两个具有相同签名的方法,只是参数修饰符不同。见@Adam Robinson的答案;这是为了确保调用者知道从方法返回后他们的变量可能会发生什么(或者在out的情况下会发生什么)。

它就在那里,这样你就明确同意你调用的方法可能会修改变量本身的值。这是C语言的要求;其他语言,如VB.NET,不需要修饰实际的方法调用,只需要方法签名。

C#使您将参数标记为
ref
/
out
,作为警告/指针,提醒程序员这些参数正在发生变化,传递的值可能会改变。例如,在这种情况下:

int myInt = 12;
string myString = Fizz(myInt);
// What is the value of myInt at this point?

我知道在上面的例子中,
myInt
的值是12,但是如果
out
ref
参数是隐式的,情况就不是这样了。

因此阅读代码的人知道你在做什么,这表明传递的变量可能会改变

它还有另外一个好处,可以阻止你意外地做这件事


在隐式(甚至默认)通过ref传递的平台上维护代码后,我想说键入3个字符对于它提供的清晰性(以及可能的合理性)来说是一个很小的代价。

他在问调用函数时为什么需要使用
ref
out
(与只需要在方法签名中将它们声明为
ref
out
不同,
ref
out
不需要做什么。对不起,我已经对问题进行了重新措辞,以消除歧义。他在问调用函数时为什么需要使用
ref
out
(与只需要在方法签名中将它们声明为
ref
out
不同),而不是
ref
out
所做的。@TJHeuvel抱歉,我的问题没有像我想的那么清楚!事实上,这是c的一个积极特征。感谢Adam,似乎重载也会加入其中。如果我将示例中的两个方法签名更改为:void DoStuff(int x,out int y)空位(整数x,整数y)然后它们可以被重载。@Grand:Yep;IL不区分
ref
out
,这就是为什么不能创建一个包含
ref
的重载和一个仅包含
out
的重载,但可以创建一个包含
ref
//code>out参数的重载,而另一个则不是。您真的不希望它这样做隐式,这样更好。只是考虑潜在的变量变化的可能性。这也有助于使RF看起来很笨拙,因此降低了它的受欢迎程度,从而使代码更易于维护。