ref和out有什么区别?(C#)

3

重复问题:https://dev59.com/FXVC5IYBdhLWcg3w9GLM - Pat
5个回答

19

对于调用者:

  • 对于 ref 参数,变量必须已经被明确赋值
  • 对于 out 参数,变量不必被明确赋值,但在方法返回后将被赋值

对于方法:

  • ref 参数开始时已经被明确赋值,您不需要为其分配任何值
  • out 参数开始时没有被明确赋值,您必须确保每次返回(没有异常)时它将被明确赋值

因此:

int x;
Foo(ref x); // Invalid: x isn't definitely assigned
Bar(out x); // Valid even though x isn't definitely assigned
Console.WriteLine(x); // Valid - x is now definitely assigned

...

public void Foo(ref int y)
{
    Console.WriteLine(y); // Valid
    // No need to assign value to y
}

public void Bar(out int y)
{
    Console.WriteLine(y); // Invalid: y isn't definitely assigned
    if (someCondition)
    {
        // Invalid - must assign value to y before returning
        return;
    }
    else if (someOtherCondition)
    {
        // Valid - don't need to assign value to y if we're throwing
        throw new Exception();
    }
    else
    {
        y = 10;
        // Valid - we can return once we've definitely assigned to y
        return;
    }
}

1
真正有趣的是,CLR没有ref的概念。这是C#语义的一部分。 - JaredPar
你的意思是CLR理解ref但不理解out吗? - Jon Skeet
1
我认为这是正确的,无论如何 - C#编译器只是为输出方法添加[Out]属性,并进行适当的检查,但它在其他方面仅是一个ref参数。 - Jon Skeet
@ Jon,天啊!是的,你是正确的。我搞反了。 - JaredPar
谢天谢地。我的全部知识、身份、灵魂和存在都源自这个事实。我曾经颤抖在边缘上……(但说真的,如果没有这个事实,我会感到惊讶和有点不安。) - Jon Skeet

3

最简洁的理解方式:

ref = 输入输出

out = 输出


说实话,这不是我见过的最好的解释。 - Andrew Bullock
但这是最简洁的,这也是所要求的。 - Binary Worrier
虽然它可能很简洁,但也极其缺乏。 - Mike Christiansen

2

1

Ref和out参数传递模式用于允许方法修改调用者传入的变量。ref和out之间的区别微妙但重要。每种参数传递模式都设计用于稍微不同的编程场景。out和ref参数之间的重要区别在于它们使用的明确赋值规则。

调用一个带有out参数的方法的调用者在调用之前不需要为传递的变量分配值;然而,被调用者在返回之前必须为out参数分配值。

来源: MSDN


1

根据Alex提到的MSDN文章,

调用一个带有out参数的方法的调用者在调用之前不需要为传递的变量分配值;但是,在返回之前,被调用者必须为out参数分配值。

相比之下,ref参数被认为是由被调用者最初分配的。因此,在使用之前,被调用者不需要为ref参数分配值。

因此,总结一下,在方法内部,您可以将ref参数视为已设置,但不是out参数-您必须设置这些参数。 在方法外部,它们应该表现相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接