C#嵌套類的使用方法及特性

        嵌套類(Nested Class)是在類中定義的類。以下把擁有內嵌類的類稱爲外部類。根據《深入理解嵌套類和內部類》嵌套類分爲靜態嵌套類和非靜態嵌套類,其中非靜態嵌套類頁被稱爲內部類。 嵌套類在UML中是composite的另外一種代碼表示形式,表示耦合度更高,並且與外部類更加緊密。

       一般類的 訪問修飾符可以定義爲默認的internal 或者public,而內嵌類就有比較多的選擇,可以是爲protected、internal、public以及默認的private。

內嵌類與外部類的訪問限制

      嵌套類可以訪問外部類的方法、屬性、字段而不管訪問修飾符的限制。如: 

 public class A
    {
        
private static int _AInt;
        
private int _instanceInt;
        
private static void AMethod()
        {
            Console.WriteLine(_AInt);
        }
        
public void SayIt()
        {
            NestedA.Method(
this);
        }
        
/*嵌套類 定義*/
        
private class NestedA
        {
            
public static void Method(A a)
            {
                
//靜態成員
                _AInt = 100;
                AMethod();
                
//實例成員
                a._instanceInt = 10;
                a.SayIt();
            }
        }
    }

      但是外部類只能夠訪問修飾符爲public、internal嵌套類的字段、方法、屬性。示例如下:

 

 public class A
    {
        
public static void AMethod()
        {
            
//成功
            NestedA.StaticMethod();
            
//編譯報錯
            NestedA._Int = 100;
            
            NestedA ins
=new NestedA();
            
//成功
            ins.Method();
            
//編譯報錯
            ins._instanceInt = 100;
        }
        
/*嵌套類 定義*/
        
private class NestedA
        {
            
private static int _Int;
            
private int _instanceInt;
            
public static void StaticMethod() { }
            
public void Method(){}
        }
    }

    嵌套類訪問外部類實例的方法、字段、屬性時候。一般在採取構造函數輸入外部類。如下:

  public class A
        {
            
private int _a;
           
            
/*嵌套類 定義*/
            
private class NestedA
            {
                
public NestedA(A a)
                {
                    a._a 
= 9;
                }              
            }
        }
 繼承

        繼承類,也就是繼承類外部類的類,只能使用父類中嵌套類的public或者internal(同一個程序集合)方法。但是繼承類可以再定義一個內嵌類並從繼承父類中嵌套類。如:

public class A
{
            
/*嵌套類 定義*/
            
protected class Nested
            {
                
protected virtual void BaseNested_Method(){}
            }
}

 
public class C : A
{
      
/*內嵌類 定義*/
      
protected class C_Nested:Nested
      {
                
protected override void BaseNested_Method()
                {
                    
//重寫部分
        }
       }
 }

      因爲C中A中繼承,因此C_Nested可以繼承Nested類,從而獲取重寫父嵌套類的機會。但是Nested必須是可繼承類及可訪問的(非private 、sealed、static)。

         嵌套類可以隨意外部類的任何數據屬性,而外部類訪問嵌套類就只能遵守訪問修飾符。從這個角度看,嵌套類是外部類的補充,通過嵌套類可以獲取更好的封裝性,增加外部類的可維護性和可讀性。       

      從程序結構看,嵌套類在邏輯上更加接近使用類。可以更有效地表示類與類之間的緊密程度。爲類管理提供除命名空間外的另一種方法。

懶加載

        嵌套類的靜態構造函數不會隨着外部類的觸發而初始化。因此可以有效地避免創建時候初始化時間,當需要使用內嵌類的時候,嵌套類纔開始初始化纔開始初始化。

public class Outside
{
    
static Outside()
    {
        Console.WriteLine(
"Outside Inilizlized");
    }
    
public void SayIt()
    {
        Nested.Run();
    }
    
private class Nested
    {
        
static Nested()
        {
            Console.WriteLine(
"Nested initilized");
        }

        
public static void Run()
        {
            Console.WriteLine(
"Nested Run");
        }
    }
}

執行結果

 Outside o = new Outside();//打印"Outside Inilizlized"
 Console.ReadLine();
 o.SayIt();
//首先打印"Nested initilized" 再打印 "Nested Run"
 Console.ReadLine();

      一般應用這個特性會在一些C#單例模式中找到,而這種模式可以被稱爲Fully lazy singleton模式。下面是簡單的演示代碼(Singleton模式可以在這裏有更加詳細的解釋):

public class Singleton
    {
        
public static Singleton Instance
        {
            
get
            {
                
return Nested.instance;
            }
        }
        
private class Nested
        {
            
public readonly static Singleton instance=new Singleton();
        }
}

 

 反射

      反射內嵌類需要使用"+"而不是我們常使用的"." 。如A類在Assembly名稱爲InsideClass中。

namespace InsideClass
{
    
public class A
    {
         
public class Nested
        {
            
protected void BaseNested_Method()
            {
            }
        }
     }
}

執行

 //成功
object o1 = System.Activator.CreateInstance("InsideClass""InsideClass.A+Nested");
 
//失敗 拋出System.TypeLoadException 異常
object o2 = System.Activator.CreateInstance("InsideClass""InsideClass.A.Nested");

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章