[C#, CSharp, C Sharp 教學 教程 教材 Tutorial] 命名空間(Namespace)
YehYeh\'s Notepad yehyeh@gmail.com 

[C#, CSharp] 命名空間(Namespace)

命名空間介紹

  • 命名空間:用來指明程式所屬範圍的機制
    • 為類別建立層級組織(Hierarchical Organization),方便管理
    • 避免相同名稱類別產生衝突
    • 控制類別的範圍
    • 功能擴充
  • 全域命名空間(Global Namespace)所有命名空間的根,若物件在定義時沒有指定命名空間,則會歸在全域命名空間底下
    • global與 :: 一起時才有作用,而不能使用global.命名空間
    • class 類別 { }
          
      class 類別1
      {
          global::類別 物件 = new global::類別();
      }
      
Δ 回到最上方

命名空間宣告

  • 使用命名空間時,源始碼通常會放在對應的同名資料匣,但並非強制
  • 宣告:
    • namespace 限定識別字 { 命名空間主體 } ;opt
      • 限定識別字即命名空間的名稱
      • namespace 命名空間
        {
            class 類別 { }
        }
        
    • 命名空間可以在編譯單元的最上層宣告 新宣告的命名空間為全域命名空間的成員
    • 命名空間可以在另一個命名空間中宣告 新宣告的命名空間為外部命名空間的成員
    • 命名空間的名稱(識別字)在其所在的命名空間中必須是唯一的
    • 命名空間一定為public,且宣告時不能指定存取修飾詞
    • 命名空間以 . 運算子做區隔
    • 限定識別字(qualified-identifier)可以是單一識別字或由 . 分隔的識別字
      namespace 命名空間1.命名空間2
      {
          class 類別1 { }
      }
      
      等同於
      namespace 命名空間1.命名空間2
      {
          class 類別1 { }       
      }
      
    命名空間宣告文法
  • 使用using命名空間指示詞 :
    using 命名空間1.命名空間2;                            
    類別 物件 = new 類別();     // 命名空間1.命名空間2.類別
    
  • 使用限定識別字:
    // 命名空間1.命名空間2.類別                           
    命名空間1.命名空間2.類別 物件 = new 命名空間1.命名空間2.類別();
    
Δ 回到最上方

控制類別的範圍

  • 當類別太多時可以用命名空間加以分類
  • 當類別名稱相同或類似時可以用命名空間加以分類
    namespace 命名空間1     // 命名空間1
    {
        class 類別1         // 命名空間1.類別1
        {
            class 類別      // 命名空間1.類別1.類別
            {
            }
        }
    
        namespace 命名空間2 // 命名空間1.命名空間2
        {
            class 類別      // 命名空間1.命名空間2.類別
            {
            }
        }
    }
    
Δ 回到最上方

功能擴充

  • 已存在的命名空間或是其它廠商開發的程式,可以宣告同名的命名空間以擴充其功能
    namespace System  //擴充.Net Framework提供的System命名空間的功能
    {
        class 類別 { }
    }
    
Δ 回到最上方

命名空間存取原則

  • 一個命名空間,不可有相同名稱(識別字)的成員
  • 存取空間時,只要由可辨識的空間開始指明,不需指明完整的空間
    namespace 空間A
    {   
        namespace 空間B
        {
            class 類別1
            {
                空間C.類別2 object2;
            }
            namespace 空間C
            {
                class 類別2 {}
            }
        }
    } 
    
  • 一個命名空間,可以使用多種指明命名空間方式
    namespace 空間A
    {   namespace 空間B
        {   class 類別1
            {
                空間C.類別2            object0;
                空間B.空間C.類別2       object1;
                空間A.空間B.空間C.類別2  object2;
            }
            namespace 空間C
            {
                class 類別2 {}
            }
        }
    }
    
  • 可在同一個敘述使用不同方式指名
    namespace 空間A
    {   namespace 空間B
        {   class 類別1
            {
                空間C.類別2 object2 = new 空間A.空間B.空間C.類別2();
            }
            namespace 空間C
            {
                class 類別2 {}
            }
        }
    } 
    
  • 存取自身空間的類別,可不指明空間
    namespace 空間A
    {   namespace 空間B
        {   class 類別1
            {
                類別2 object2;
            }                                            
            class 類別2 {}                                            
        }
    }
    
  • 存取內層空間的類別時需明確指明命名空間
  • 預設存取空間為由本層開始,若為最裡層則由本層或本層的上一層開始 命名空間範例
  • 存取內層空間的類別時,可由內層、本層、外層任一層開始指明
    namespace 空間A             //外層
    {   namespace 空間B         //本層
        {   class 類別1
            {                                                
                空間C.類別2           objectB1;   // 由內層開始指明命名空間
                空間B.空間C.類別2      objectB2;   // 由本層開始指明命名空間
                空間A.空間B.空間C.類別2 objectB3;   // 由外層開始指明命名空間
            }
            namespace 空間C     //內層
            {
                class 類別2 { }
            }
        }
    }
    
  • 存取外層空間的類別時,可不指明命名空間
    namespace 空間A         //外層
    {   class 類別1  { }
        namespace 空間B     //本層
        {   class 類別2 
            { 
                類別1 object1;
            }
        }
    } 
    
  • 存取外層空間的類別時,若不指明空間,愈靠近本層的外層有愈高的優先權
    namespace 空間A                 //最外層
    {   class 類別1 { }                                        
        namespace 空間B             //外層
        {   class 類別1 { }
            namespace 空間C         //本層
            {   class 類別2 
                { 
                    類別1 object1;  // 類別1 = 空間A.空間B.類別1
                }
            }
        }
    }
    
  • 可使用using指示詞設定程式中預設搜尋的空間
    using 空間A.空間B;
    
    namespace 空間A
    {   class 類別1 { }                                        
        namespace 空間B
        {   class 類別1 { }                                            
        }
    }
    
    namespace 空間D
    {   class 類別
        {
            類別1 object1;  // 類別1 = 空間A.空間B.類別1
        }
    }
    
  • 使用using指示詞時,本層內的類別仍有較高的優先權
    using 空間A.空間B;
    
    namespace 空間A         // 與類別2同層
    {   class 類別1 { }
    
        class 類別2
        {   
            類別1 object1;  // 類別1 = 空間A.類別1
        }
    
        namespace 空間B     //內層
        {   
            class 類別1 { }                                            
        }
    }
    
  • 全域命名空間(global::)為所有命名空間的根
  • 當同名字的命名空間太多,且階層複雜時,可以使用全域命名空間來確保存取到指定的類別
    namespace 空間A
    {   
        class 類別1 { }
        namespace 空間A
        {   
            class 類別1 { }                                            
            namespace 空間A
            {   
                class 類別1 { }
                class 類別2
                {
                    //類別1 = 空間A.空間A.空間A.類別1
                    類別1   object1;  
    
                    //空間A.類別1 = 空間A.空間A.空間A.類別1
                    空間A.類別1 object2;  
    
                    // X 不合法
                    空間A.空間A.類別1   object3;
    
                    //global::空間A.類別1 = 空間A.類別1
                    global::空間A.類別1 object4;
    
                    //global::空間A.空間A.類別1 = 空間A.空間A.類別1
                    global::空間A.空間A.類別1 object5; 
                }
            }
        }
    }
    
Δ 回到最上方

綜合範例

  • 綜合範例
    namespace 空間A             //外層
    {
        namespace 空間B         //本層
        {
            class 類別1
            {
                public 類別1() { System.Console.WriteLine("A"); }
    
                // 顯示: B
                空間C.類別2  objectB1 = new 空間C.類別2();
    
                // 顯示: B
                空間B.空間C.類別2  objectB2 = new 空間B.空間C.類別2();
    
                // 顯示: B
                空間A.空間B.空間C.類別2  objectB3 = new 空間B.空間C.類別2();
    
                // 顯示: B
                空間A.空間B.空間C.類別2  objectB4 = new 空間A.空間B.空間C.類別2();
    
                // 顯示: B
                空間B.空間C.類別2  objectB5 = new 空間A.空間B.空間C.類別2();
    
                // 顯示: B
                global::空間A.空間B.空間C.類別2 objectB6 
                        = new global::空間A.空間B.空間C.類別2();
                                    
                // X 錯誤寫法
                類別2 objectB = new 類別2();
    
                // 顯示: C
                空間A.空間C.類別1  objectC1 = new 空間A.空間C.類別1();
    
                // 顯示: D
                空間A.空間C.空間C.類別2  objectD1 = new 空間A.空間C.空間C.類別2();
            }
    
            namespace 空間C     //內層
            {
                class 類別2
                {
                    public 類別2() { System.Console.WriteLine("B"); }
                }
            }
        }
    
        namespace 空間C
        {
            class 類別1
            {
                public 類別1() { System.Console.WriteLine("C"); }
            }
    
            namespace 空間C
            {
                class 類別2
                {
                    public 類別2() { System.Console.WriteLine("D"); }
    
                    // 顯示: A
                    空間B.類別1         objectA = new 空間B.類別1();
    
                    // 顯示: B
                    空間B.空間C.類別2   objectB = new 空間B.空間C.類別2();
    
                    // 顯示: C
                    類別1               objectC = new 類別1();
    
                    // 顯示: D
                    空間C.類別2         objectD = new 空間C.類別2();
    
                    // X 錯誤寫法
                    空間C.類別1         objectC = new 空間C.類別1();
                }
            }
        }
    }
    
     
    
            
Δ 回到最上方