Curious C# using statement expansion

前端 未结 5 932
一个人的身影
一个人的身影 2021-01-17 07:31

I\'ve run ildasm to find that this:

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

generates IL cod

相关标签:
5条回答
  • 2021-01-17 07:57

    It appears that your comment:

    "If there is some fear that some intervening steps might come between the Simple constructor and the beginning of the try block, then that would really be a problem because then an exception might be thrown that would prevent the finally block from executing at all."

    is possibly dead on. See:

    Atomicity & Asynchronous Exception Failures

    I also want to note the issue(s) with WCF and using:

    Avoiding Problems with the Using Statement and WCF Service Proxies which references:

    Avoiding Problems with the Using Statement

    0 讨论(0)
  • 2021-01-17 07:59

    No, the finally block will ALWAYS be executed. You may not be getting the object from a new but from some other function that returns your object - and it might return NULL. using() is your friend!

    dss539 was kind enough to suggest I include his note:

    using(Simple simp = null) 
    

    is yet another reason that the expansion must check for null first.

    0 讨论(0)
  • 2021-01-17 08:13

    The code must be translated this way to avoid possible NullReferenceException when disposing the object. As per C# language reference, the using statement accepts not only a local variable declaration as its first nonterminal resource_acquisition symbol, but any expression. Consider the following code:

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

    Clearly, unless null-conditional @object?.Dispose() in the finnaly block, an exception would ensue. The null check is superfluous only when the expression is of a non-nullable value type (non-nullable struct). And indeed, according to the aforementioned language reference it is absent in such case.

    0 讨论(0)
  • 2021-01-17 08:15

    using(Simple simp = null) is yet another reason that the expansion must check for null first.

    0 讨论(0)
  • 2021-01-17 08:23

    MSDN on the using statement.

    What I think is strange is that it doesn't expand to:

    Simple simp = new Simple();
    Simple __compilergeneratedtmpname = simp;
    try
    {
        Console.WriteLine("here");
    }
    finally
    {
        if(__compilergeneratedtmpname != null)
        {
            __compilergeneratedtmpname.Dispose();
        }
    }
    
    0 讨论(0)
提交回复
热议问题