為了了解兩種類型的其他不同點,分別給出它們的示例代碼:
// 一般類
StandardClass A = new StandardClass();
Console.WriteLine(A);
StandardClass B = new StandardClass();
Console.WriteLine(B);
StandardClass C = new StandardClass();
Console.WriteLine(C);
// 泛型類
GenericClass<bool > gA = new GenericClass<bool >();
Console.WriteLine(gA);
GenericClass<int> gB = new GenericClass<int>();
Console.WriteLine(gB);
GenericClass<string> gC = new GenericClass<string>();
Console.WriteLine(gC);
GenericClass<string> gD = new GenericClass<string>();
Console.WriteLine(gD);
上述代碼輸出結果如下:
There are 1 instances of CSharpRecipes.Generics+StandardClass which contains 0 items of type System.Object[]...
There are 2 instances of CSharpRecipes.Generics+StandardClass which contains 0 items of type System.Object[]...
There are 3 instances of CSharpRecipes.Generics+StandardClass which contains 0 items of type System.Object[]...
There are 1 instances of CSharpRecipes.Generics+GenericClass`1[System.Boolean] which contains 0 items of type System.Boolean[]...
There are 1 instances of CSharpRecipes.Generics+GenericClass`1[System.Int32] which contains 0 items of type System.Int32[]...
There are 1 instances of CSharpRecipes.Generics+GenericClass`1[System.String] which contains 0 items of type System.String[]...
There are 2 instances of CSharpRecipes.Generics+GenericClass`1[System.String] which contains 0 items of type System.String[]...
討論
泛型中的類型參數允許您在不知道使用何種類型的情況下提供類型安全的代碼。在很多場合下,您希望類型具有某些指定的特征,這可以通過使用類型約束(秘訣4.12)來實現。方法在類本身不是泛型的情況下也可以擁有泛型類型的參數。秘訣4.9為此演示了一個例子。
注意當StandardClass擁有三個實例,GenericClass有一個聲明為<bool >類型的實例,一個聲明為<int>類型的實例,兩個聲明為<string>類型的實例。這意味著所有非泛型類都創建同一.NET類型對象,而所有泛型類都為指定類型實例創建自己的.Net類型對象。
示例代碼中的StandardClass類有三個實例,因為CLR中只維護一個StandardClass類型。而在泛型中,每種類型都被相應的類型模板所維護,當創建一個類型實例時,類型實參被傳入。說得更清楚一些就是為GenericClass<bool >產生一個類型,為GenericClass<int>產生一個類型,為GenericClass<string>產生第三個類型。
內部靜態成員_count可以幫助說明這一點,一個類的靜態成員實際上是跟CLR中的類型相連的。CLR對於給定的類型只會創建一次,並維護它一直到應用程序域卸載。這也是為什麼在調用ToString方法時,輸出顯示有StandardClass的三個實例,而GenericClass<T>類型有1和2個實例。