溫故之C# using注意事項

JameLee發表於2018-06-14

說明:溫故即溫習之前已經掌握但比較模糊的知識;取自於“溫故而知新”

using 在C#中有三種使用場景,如下:

  1. 引用名稱空間;
  2. 為名稱空間取一個易於使用的別名;
  3. 幫助管理非託管資源。

引用名稱空間

使用場景:當需要使用某一個名稱空間中的型別時,通過using可以免去引用該型別時,輸入完全限定名的痛苦(因為名稱空間大多比較長)。

當不引入名稱空間的時候,需要這樣引用名稱空間中的型別

namespace UsingDemo {
    class Program {
        static void Main(string[] args) {
            System.Collections.Generic.List<string> tmp = new System.Collections.Generic.List<string>();
        }
    }
}
複製程式碼

當引用了名稱空間的時候,僅需要按下面引用即可

using System.Collections.Generic;

namespace UsingDemo {
    class Program {
        static void Main(string[] args) {
            List<string> tmp = new List<string>();
        }
    }
}
複製程式碼

引用名稱空間時需注意名稱空間引用位置:

  1. 引用位置可在檔案頂部或當前名稱空間的頂部;
  2. 不可在類的內部、函式內部、屬性內部引用,否則會編譯錯誤。

正確示例如下:

// 在檔案頂部引入
using System.Collections.Generic;

namespace UsingDemo {
     class Program {
         static void Main(string[] args) {
             List<string> tmp = new List<string>();
         }
     }
 }
複製程式碼
namespace UsingDemo {
   // 當前名稱空間的頂部引入
    using System.Collections.Generic;
    class Program {
        static void Main(string[] args) {
            List<string> tmp = new List<string>();
        }
    }
}
複製程式碼

錯誤示例如下(會編譯錯誤,即程式碼下面會有很多紅色的波浪線):

image

名稱空間別名

使用場景:引入的多個名稱空間中的型別產生衝突,並且衝突的名稱空間都是程式需要的。

比如以下程式碼,編譯器會告訴我們,有多個可以匹配的型別(即有歧義):

image

則可以通過別名的方式來解決此問題(不用為每一個衝突的名稱空間取別名):

image
注意第二行中程式碼using WM = System.Windows.Media;,此處就是將WM定義為名稱空間System.Windows.Media; 的別名,因此後續才可以通過【別名.型別】的方式引用,如下:

WM.Color color2 = new WM.Color();
複製程式碼

幫助管理非託管資源

使用場景:

  • 當程式需要使用非託管資源,如檔案操作、網路操作、資料庫操作等,使用using對其管理會更方便、安全;
  • 需要在GC的時候強制回收的物件(如過多的大圖,則可實現IDisposable介面,進行強制管理 );
  • 程式中,需要非託管資源的生命週期需要與類相同時,則可以通過為該類實現IDisposable介面,來更加方便的管理非託管資源。

示例程式碼如下:

// 示例一
namespace UsingDemo {
    class Program {
        static void Main(string[] args) {
            using (FileStream fs = new FileStream("C://using_demo.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
                byte[] data = Encoding.UTF8.GetBytes("Hello Using!");
                fs.Write(data, 0, data.Length);
            }
        }
    }
}
// 示例二: 非託管資源的生命週期需要與類相同
namespace UsingDemo {
    class Demo : IDisposable {
        private FileStream fileStream;
        public void Dispose() {
            // 此處手動釋放資源 
            fileStream?.Dispose();
        }
    }

    class Program {
        static void Main(string[] args) {
            using (Demo demo = new Demo()) {
            }
        }
    }
}
複製程式碼

注意事項:

  • using只能用於實現了IDisposable介面的型別,不能為未實現IDisposable介面的型別使用using語句,否則會出現編譯錯誤;

    image
    實現了IDisposable介面之後:
    實現了IDisposable介面

  • 如果有多個非託管資源需要管理,則使用巢狀的using語句將會更加合適,但內層using最好不要有異常產生,否則內層using塊引發異常時,則有可能無法正確釋放外層using塊的資源; 鑑於此,不建議使用巢狀的using語句

  • using語句支援初始化多個變數,但前提是這些變數的型別必須相同。

    image


至此,C#中 using的使用及其注意事項講解完畢,歡迎您來探討!個人微信二維碼如下:

image

相關文章