簡體   English   中英

捕獲使用塊內的異常與使用塊外的異常 - 哪個更好?

[英]Catch exceptions within a using block vs outside the using block - which is better?

這兩段代碼之間有什么區別,哪種方法更好。

try
{
    using()
    { 
      //Do stuff
    }
}
catch
{
    //Handle exception
}


using()
{
    try
    {
         //Do stuff
    }
    catch
    {
        //Handle exception
    }
}

存在差異,但它歸結為使用塊創建自己的try和scope塊這一事實。

try
{
    using(IDisposable A = GetDisposable())
    { 
      //Do stuff
    }
}
catch
{
    //Handle exception
    // You do NOT have access to A
}


using(IDisposable A = GetDisposable())  //exception here is uncaught
{
    try
    {
         //Do stuff
    }
    catch
    {
        //Handle exception
        // You DO have access to A
    }
}

這些塊之間存在差異。 在第二種情況下,如果在using()行中拋出異常,則不會捕獲異常(例如,實例化IDisposable對象並且構造函數拋出異常)。 哪一個更好將取決於您的具體需求。

是。 在第一個中,您正在“使用”的資源將在執行catch塊之前被釋放。 在后來,它將在之后處理。 而且,“foo”語句不在catch子句的范圍內。 “使用”塊幾乎就是語法糖

using (foo)
{
}

try
{
  foo;
}
finally
{
  foo.Dispose();
}

沒有上下文,哪種行為“更好”並不明顯。

如上所述,只有第一種方法會捕獲IDisposable對象初始化中的異常,並且將使對象具有catch塊的范圍。

此外,catch和finally塊的操作順序將根據其嵌套而翻轉。 請看以下示例:

public class MyDisposable : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("In Dispose");
    }

    public static void MethodOne()
    {
        Console.WriteLine("Method One");
        using (MyDisposable disposable = new MyDisposable())
        {
            try
            {
                throw new Exception();
            }
            catch (Exception ex)
            {
                Console.WriteLine("In catch");
            }
        }
    }

    public static void MethodTwo()
    {
        Console.WriteLine("Method Two");
        try
        {
            using (MyDisposable disposable = new MyDisposable())
            {
                throw new Exception();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("In catch");
        }
    }

    public static void Main()
    {
        MethodOne();
        MethodTwo();
    }
}

這將打印:

Method One
In catch
In Dispose
Method Two
In Dispose
In catch

最終,您可以結合使用這兩種方法來克服這兩個缺點

IFoo f;
try{
  f = new Foo();
  f.Bar();
catch{
  // Do something exceptional with f
} finally{
  if(f != null) f.Dispose();
}

我猜你的意思是:

using (var x = new Y(params))
{
}

在這兩種情況下? 然后明顯的區別是x的范圍。 在第二種情況下,您可以在catch子句中訪問x 在第一種情況下,你不能。

我也會借此機會提醒你不要“處理”異常,除非你真的可以做些什么。 這包括記錄異常,這是可以的,除非你正在操作的環境為你做日志記錄(默認情況下是ASP.NET 2.0)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM