尽管将未实例化的变量作为参数传递,为什么此代码仍然有效?

时间:2015-03-10 23:47:00

标签: c# .net

以下是使用TryParse

的语法
int a;
bool success = Int32.TryParse("0",out a);

但这究竟是如何运作的呢?变量a尚未实例化!

3 个答案:

答案 0 :(得分:3)

不需要在调用方法中实例化out参数。事实上,调用方法中的任何值都会被被调用的方法覆盖。

示例:

public static bool MyTryParse(string value, out int result){
    int hold;
    if (int.TryParse(value, out hold)){
        result = hold;
        return true;
    }

    // Comment out the following line and you'll get a compile error
    result = default(int); // This method MUST set result
    return false;
}

如您所见,即使调用者在参数上设置了一些值,该值也会被覆盖。

此外,请注意,如果使用引用类型,则其工作方式完全相同。


来自“ out (C# Reference) ”:

  

out 关键字会导致参数通过引用传递。

     

...

     

虽然作为out参数传递的变量在传递之前不必初始化,但是在方法返回之前需要调用方法来赋值。

     

...

我不知道的事情:

  

但是,如果一种方法采用 ref out 参数而另一种方法都不使用,则可以进行重载,如下所示:

class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) { i = 5; }
}

答案 1 :(得分:1)

out参数的语义是在调用方法时不需要先分配变量。在C#规范的说法中,编译器将变量标记为“明确赋值”,这意味着在后面的表达式中使用它是合法的,因为它必须在方法内部用值初始化。

此规则在C#规范的第5.1.6节中说明:

  

在将变量作为函数成员或委托调用中的输出参数传递之前,无需明确赋值变量。

这与ref参数不同,该参数在传递给方法之前必须明确赋值,但该方法将能够修改变量。

答案 2 :(得分:0)

您使用out关键字所做的工作是通过引用您的a。看看生成的IL:

enter image description here

如果你在IL_0006行看到有一条名为ldloca.s的指令:

  

将特定索引处的局部变量的地址加载到评估堆栈中,简称。

总结:out会使参数通过引用传递,因此当您将变量传递给TryParse时,为变量a分配一个转换后传递的字符串的值。

希望它有所帮助。