输出参数和异常

Nik*_*las 32 c# exception out

说我有以下代码:

    static void Fjuk(out string str)
    {
        str = "fjuk!";
        throw new Exception();
    }

    static void Main(string[] args)
    {
        string s = null;
        try
        {
            Fjuk(out s);
        }
        catch (Exception)
        {
            Console.WriteLine(s ?? "");
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我测试它时,s已被初始化为"fjuk!" 当它在catch块中使用时.
这是由规范保证还是依赖于实现?(我已经搜索了C#3规范,但无法找到我自己)

Mar*_*ell 26

差不多,这是一个方面的out意义; 首先,请注意out并不存在 - 我们只需要考虑ref(out只是ref在编译器中进行一些"明确赋值"调整).ref意味着"传递这个地址" - 如果我们通过地址更改值,那么立即显示- 它毕竟是更新堆栈上Main的内存.它不能抽象这个(延迟写入),因为该值可能是,例如,一些超大的结构,ref专门用于避免在堆栈上复制它(在XNA中广泛使用的方法等).


gdo*_*ica 7

它是"保证"的,因为out参数会使用参数更改值memory address.

out关键字使参数通过引用传递.这类似于ref关键字,除了ref要求在传递之前初始化变量.

来自MSDN


Guf*_*ffa 5

如果方法抛出异常,则不保证设置输出参数。如果方法无异常退出,则保证设置输出参数。

在您的情况下,该方法将始终设置输出参数,但编译器不会以这种方式分析该方法的代码。如果方法异常退出,输出参数仍然不被认为是明确设置的。

您在异常处理程序中的代码不依赖于由方法调用设置的变量,因为您是在创建变量时对其进行设置的。如果在创建时没有设置变量,异常处理程序就不能使用它,因为它不能保证被设置:

string s;
try {
  Fjuk(out s);
  Console.WriteLine(s); // here the variable is guaranteed to be set
} catch (Exception) {
  Console.WriteLine(s); // here it's not, so this won't compile
}
Run Code Online (Sandbox Code Playgroud)