【问题标题】:ref and out with value type variables带有值类型变量的 ref 和 out
【发布时间】:2015-04-14 19:22:56
【问题描述】:

msdn documentation on out 表示作为 out 传递的参数必须在函数内部分配一个值。来自网站的示例:

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
       // value is now 44
    }
 }

根据我的理解,当声明int“值”时,它已经被分配了一个默认值0(因为int是一种值类型,不能为空。)那么为什么“方法”有必要修改它的值?

同样,如果用“ref”代替out,是否需要初始化“value”?

有这样的问题What's the difference between the 'ref' and 'out' keywords?,但没有人愿意把 2 和 2 放在一起。

【问题讨论】:

    标签: c# methods out ref


    【解决方案1】:

    根据我的理解,当声明 int“值”时,它是 已经分配了一个默认值 0(因为 int 是一个值类型并且 不能为空。)

    不,那不正确。

    局部变量在创建时没有赋值。局部变量的空间是通过移动堆栈指针为它们在堆栈上腾出空间来创建的。该内存区域没有被清除,它将包含碰巧存在的任何值。

    编译器强制你在变量可以使用之前给它赋值,这样它原本包含的“垃圾”值就永远不会被使用。

    类似地,如果使用“ref”而不是 out,会有任何 需要初始化“值”吗?

    该值不需要在方法中设置,因为它已经有一个值。用于调用该方法的变量需要初始化:

    static void Method(ref int i) {
        // doesn't need to set the value
    }
    
    static void Main() {
        int value;
        value = 42; // needs to be initialised before the call
        Method(ref value);
       // value is still 42
    }
    

    【讨论】:

    • 我认为没有任何“垃圾”价值。 int 将被分配一个默认值 0 并且当仅声明一个变量时它是未分配的。 .Net中没有像C、C++这样的垃圾值的概念。
    • out 只指定方法修改参数的值。即使该参数被分配了一些“非垃圾”值。
    【解决方案2】:

    默认情况下不为 int 赋值,即使有默认值...试试这个:

    Console.WriteLine(default(int)); // output = '0'
    int foo;
    Console.WriteLine(foo); // compile error - Use of unassigned local variable
    

    out 参数的约定是方法保证为它分配一个值。 ref 参数的合约没有这样的保证。

    【讨论】:

      【解决方案3】:

      必须为变量赋值。但是您在帖子中提到的out 参数的概念具有更多的语义含义。

      如果您传递out 参数,您希望您调用的函数必须分配它。 C# 编译器只是强制执行“优秀程序员”技能来控制编译时间,以获得更好的代码风格。

      【讨论】:

        【解决方案4】:

        有时您需要从您的方法中返回多个值,因此在这种情况下,您可以通过 ref 和 out 参数返回这些额外的值。对这些的一个很好的参考是来自 .NET 框架的“TryParse”方法,例如“Int32.TryParse 方法”

        [1]: https://msdn.microsoft.com/en-us/library/f02979c7%28v=vs.110%29.aspx

        您可以在 MSDN 中的上述链接上找到更多信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-09-19
          • 1970-01-01
          • 2011-02-17
          • 2020-09-23
          • 2010-12-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多