26

我已经运行 ildasm 来发现:

    using(Simple simp = new Simple())
    {
        Console.WriteLine("here");
    }

生成与此等效的 IL 代码:

    Simple simp = new Simple();
    try
    {
        Console.WriteLine("here");
    }
    finally
    {
        if(simp != null)
        {
            simp.Dispose();
        }
    }

问题是为什么它会在finally中检查null?finally 块只有在 try 块被执行时才会被执行,而 try 块只有在 Simple 构造函数成功(即不抛出异常)时才会被执行,在这种情况下 simp 将是非空的。(如果有人担心在 Simple 构造函数和 try 块的开头之间可能会出现一些干预步骤,那么这确实是一个问题,因为可能会引发异常,从而完全阻止 finally 块的执行。)那么,到底为什么?

抛开(请)使用语句是否比 try-finally 更好的论点,我将 try-finally 块编写为:

    Simple simp = new Simple();
    try
    {
        Console.WriteLine("here");
    }
    finally
    {
        simp.Dispose();
        simp = null;        // sanity-check in case I touch simp again
                            // because I don't rely on all classes
                            // necessarily throwing
                            // ObjectDisposedException
    }
4

5 回答 5

22

不,finally 块总是会被执行。您可能不是从新的对象获取对象,而是从返回对象的其他函数获取对象 - 它可能返回 NULL。using() 是你的朋友!

dss539 非常友好地建议我包括他的注释:

using(Simple simp = null) 

扩展必须首先检查 null 的另一个原因。

于 2009-06-03T20:25:13.553 回答
11

using(Simple simp = null)扩展必须首先检查 null 的另一个原因。

于 2009-06-03T20:31:15.833 回答
4

MSDN关于 using 声明。

我认为奇怪的是它没有扩展到:

Simple simp = new Simple();
Simple __compilergeneratedtmpname = simp;
try
{
    Console.WriteLine("here");
}
finally
{
    if(__compilergeneratedtmpname != null)
    {
        __compilergeneratedtmpname.Dispose();
    }
}
于 2009-06-03T21:04:33.113 回答
2

看来您的评论:

“如果有人担心在 Simple 构造函数和 try 块的开头之间可能会出现一些干预步骤,那么这确实是一个问题,因为可能会引发异常,从而完全阻止 finally 块的执行。”

可能已经死了。看:

原子性和异步异常失败

我还想注意 WCF 的问题并使用:

使用引用的 Using 语句和 WCF 服务代理避免出现问题:

避免使用语句的问题

于 2010-03-23T15:26:01.560 回答
0

必须以这种方式翻译代码以避免在处理对象时可能出现NullReferenceException 。根据C# 语言参考using 语句不仅接受局部变量声明作为其第一个非终结resource_acquisition符号,还接受任何表达式。考虑以下代码:

DisposableType @object = null;
using(@object) {
    // whatever
}

显然,除非块中有空条件,否则@object?.Dispose()finnaly发生异常。只有当表达式是不可为空的值类型(不可为空的结构)时,空检查才是多余的。事实上,根据上述语言参考,在这种情况下它是不存在的。

于 2020-07-01T17:50:14.333 回答