首頁 > 軟體

C#中using語句的用法

2022-03-21 13:02:49

一、using語句

using可以算是.NET中新的語法元素,它清楚地說明一個通常比較佔用資源的物件何時開始使用和何時被手動釋放。當using可以被使用時,建議儘量使用using語句。至今為止,使用using語句發現它帶給程式設計師的只有優點,而沒有任何弊端。

在.NET的環境中,託管的資源都將由.NET的垃圾回收機制來釋放,而一些非託管的資源則需要程式設計師手動地將它們釋放。.NET提供了主動和被動兩種釋放非託管資源的方式,即IDisposable介面的Dispose方法和型別自己的Finalize方法。任何帶有非託管資源的型別,都有必要實現IDisposable的Dispose方法,並且在使用完這些型別後需要手動地呼叫物件的Dispose方法來釋放物件中的非託管資源。

如果型別正確地實現了Finalize方法,那麼即使不呼叫Dispose方法,非託管資源也最終會被釋放,但那時資源已經被很長時間無畏地佔據了。

using語句的作用就是提供了一個高效的呼叫物件Dispose方法的方式。對於任何IDisposable介面的型別,都可以使用using語句,而對於那些沒有實現IDisposable介面的型別,使用using語句會導致一個編譯錯誤。

先來看一個using語句的基本語法:

using(StreamWriter sw= new StreamWriter())
{
    // 中間處理邏輯
}

在上面程式碼中,using語句一開始定義了一個StreamWriter的物件,之後在整個語句塊中都可以使用sw,在using語句塊結束的時候,sw的Dispose方法將會被自動呼叫。using語句不僅免除了程式設計師輸入Dispose呼叫的程式碼,它還提供了機制保證Dispose方法被呼叫,無論using語句塊順利執行結束,還是丟擲了一個異常。下面的程式碼演示了using的這一保護機制。

using System;

namespace usingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // 使用using
                using (MyDispose md = new MyDispose())
                {
                    md.DoWork();
                    // 丟擲一個異常來測試using
                    throw new Exception("丟擲一個異常");
                }
            }
            catch
            {

            }
            finally
            {
                Console.ReadKey();
            }
        }
    }

    /// <summary>
    /// 繼承自IDisposable介面,僅僅用來做測試,不使用任何非託管資源
    /// </summary>
    public class MyDispose : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("Dispose方法被呼叫");
        }
        public void DoWork()
        {
            Console.WriteLine("做了很多工作");
        }
    }
}

在上面的程式碼中,using語句塊丟擲了一個異常,而該異常知道using語句結束後才被捕獲。由於有了using語句的存在,即使異常被丟擲,MyDispose的物件md的DIspose方法仍然被呼叫。 。程式輸出結果如下:

事實上,C#編譯器為using語句自動新增了try/finally塊,所以Dispose方法能夠保證被呼叫到,所以如下兩段程式碼經過編譯後內容將完全一致:

using (MyDispose md = new MyDispose())
{
      md.DoWork();
}

MyDispose md;
try
{
    md = new MyDispose();
    md.DoWork();
}
finally
{
    md.Dispose();
}

在徹底瞭解了using的實現原理以後,還應該注意一點使用using時常犯的錯誤,那就是千萬不要試圖在using語句塊外初始化物件 ,如下面程式碼所示:

MyDispose md = new MyDispose();
using (md)
{
    md.DoWork();
}

看上去似乎沒有任何問題,但是在多執行緒的程式中,上述程式碼就會有隱患。試想當md被初始化後程式突然產生一個異常而中斷,那md物件中的非託管資源將沒有機會得到釋放,這對於系統來說危害是相當大的。所以在任何時候都應該在using語句中初始化需要使用的物件。

二、總結

using語句為實現了IDisposable的型別物件呼叫Dispose方法,using語句能夠保證使用的物件的Dispose方法在using語句塊結束時被呼叫,無論是否有異常被丟擲。C#編譯器在編譯時自動為using語句加上try/finally塊,所以using的本質和異常捕獲語句一樣,但是語法更為簡潔。所有using使用的物件都應該在using語句開始後再初始化,以保證所有的物件都能夠被Dispose。

到此這篇關於C#中using語句用法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com