【问题标题】:What is the purpose of the "out" keyword at the caller (in C#)?调用者(在 C# 中)的“out”关键字的目的是什么?
【发布时间】:2009-09-08 13:11:31
【问题描述】:

当一个 C# 函数有一个输出参数时,你可以如下说明:

private void f(out OutputParameterClass outputParameter);

这表明在调用函数时不必初始化参数。但是,当调用这个函数时,你必须重复out关键字

f(out outputParameter);

我想知道这有什么好处。为什么需要重复部分功能规范?有人知道吗?

【问题讨论】:

    标签: c# parameters ref out


    【解决方案1】:

    这意味着你知道你在做什么——你承认它是一个out 参数。您真的希望完全不同的行为无声无息地发生吗?顺便说一句,ref 也是如此。

    (您也可以基于按值与 out/ref 重载,但我不建议这样做。)

    基本上,如果您有一个(未捕获的)局部变量并将其用作非输出/引用参数,则您知道该变量的值不会在方法内更改。 (如果它是引用类型变量,那么它所引用的对象中的数据可能会发生变化,但这是非常不同的。)

    这避免了您在 C++ 中遇到的那种情况,您在不知不觉中通过引用传递了一些东西,但假设值没有改变......

    【讨论】:

    • 没错。如果你的变量被被调用者无意识地改变了,这可能会引起巨大的头痛。
    • 在这里! PHP“通过引用返回”(或通过引用传递参数,同样的事情)让您通过在分配返回值时排除与符号来忽略“通过引用”。谈论一个令人发狂的错误,当您遗漏的只是某处的&符号时,您会发现它。在 C# 中要求“out”是避免此类错误的最明智的方法。
    • @Dimitri:不,他们不是。引用是按值传递的。有一个巨大的差异。请阅读pobox.com/~skeet/csharp/parameters.html
    • Dimitri C:引用 Jon 的话:“根本不传递对象。引用是按值传递的。”
    • @Pierre-Alain:重载可能会让人感到困惑。通过参数如何传递这样一个相对微妙的事情进行重载几乎必然会引起混乱。
    【解决方案2】:

    这是一个设计特点。很明显,这不是必需的,但它有助于提高可读性。

    【讨论】:

      【解决方案3】:

      虽然我不知道这种决定的由来,但我知道它有超载的目的。

      在同一个类中创建这两个函数是完全合法的:

      private void f(out OutputParameterClass outputParameter);
      

      private void f(OutputParameterClass outputParameter);
      

      在调用此类重载时指定 out 关键字是有意义的。

      【讨论】:

        【解决方案4】:

        为了可读性,了解该方法可以/将对您的变量做什么。

        从 MSDN 获得更多信息: http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx

        方法的调用者接受一个 out 参数不是必需的 分配给作为传递的变量 调用前的 out 参数; 但是,被叫方必须 之前分配给 out 参数 回来了。

        【讨论】:

          【解决方案5】:

          我能看到的唯一原因是确保函数的用户知道这个参数的值可以被函数修改。我认为这是一件好事。

          【讨论】:

          • 不仅可以修改——它被修改。
          • 丹尼尔:不是。它可以保持功能不变。 out 由编译器强制执行。如果声明函数是用另一种语言编写的,它可能会选择不强制执行明确赋值。
          • 用另一种语言?哪一个?
          • 例如,您在 IL 中制作自己的函数并使用 out 属性装饰它。然后你会有一个 C# 方法调用它。
          • 多么典型:] 好吧,无论如何,C# 中的 out 参数(这是问题的标签)必须在函数中分配。当然你可以试着绕​​过它,但我认为在不尊重它们的语义的情况下使用这种修饰符 (out, ref) 没有多大意义。
          【解决方案6】:

          我认为这是一个一致性和清晰性的问题。

          显然,没有编译器也可以做得很好。但是,添加 out 关键字后,您的意图就很明确了,代码也变得更加清晰易读。

          【讨论】:

            【解决方案7】:

            我得到的最佳答案是plinth发表的评论:

            重复out/ref的最重要原因是如果你调用的函数被重构为不同的签名,你会得到一个编译错误。最值得注意的是,如果一个参数从非输出变为输出,您马上就会知道。

            【讨论】:

              【解决方案8】:

              为了清楚起见,您可能必须使用out。如果您不查看方法签名就不会知道。

              【讨论】:

              • 由于 out 和 ref 之间的明确分配差异,您得到的示例不起作用。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-08
              • 2020-04-23
              • 2011-12-04
              • 2022-11-29
              相关资源
              最近更新 更多