這個系列沒有先后順序,主要是為了加深自己的理解,通過這樣記錄自己也會在過程中去產生跟多的思考。從零開始的學習,就借這個自己記錄一下,結合的書籍是《C#圖解教程(第四版)》和自己的腦洞理解,不那么靠譜還請見諒~
泛型
C#提供了六種自定義的類型(class、struct、array、enum、delegate、interface),通過這六種類型我們已經可以去建立很復雜具體的對象。有時我們會為了一個用途去寫某個模塊(記作MyStruct),但事后發現該模塊其實還可以用在別的地方,但是由于處理的數據不同這時候可能映入腦中的是,大不了在寫一個模塊,改變一下數據類型。這個方法確實能解決這個問題,但如果太多的情況下要使用這個模塊這種簡單的方法無疑是增加了代碼的耦合。
而泛型便可以很好的解決這個問題,C#提供了五種泛型(類、結構、接口、委托和方法)
下面則是一個類泛型的例子
class MyStruct {
const int lenght = 10;
private int[] arry;
private int index = 0;
public void Push(int i) {
if (arry == null)
arry = new int[lenght];
arry[index] = i;
index++;
}
public int Peek()
{
return arry[index-1];
}
}
class MyStruct<T>
{
const int lenght = 10;
private T[] arry;
private int index = 0;
public void Push(T i)
{
if (arry == null)
arry = new T[lenght];
arry[index] = i;
index++;
}
public T Peek()
{
return arry[index - 1];
}
}
class Program
{
static void Main(string[] args)
{
int a = 12;
int b = 10;
string m = "Hello";
MyStruct myStruct1 = new MyStruct();
MyStruct<string> myStruct2 = new MyStruct<string>();
myStruct1.Push(a);
myStruct1.Push(b);
myStruct2.Push(m);
Console.WriteLine(myStruct1.Peek());
Console.WriteLine(myStruct2.Peek());
}
}
通過泛型,可以非常方便去重用一些模塊。T在這里是一個占位符,也可以用其他來代替。
泛型類的聲明如下:
-在類名之后放置一組尖括號。
-在尖括號中用逗號分隔的占位符字符串來表示希望提供的類型。這叫做類型參數(typeparameter)。
-在泛型類聲明的主體中使用類型參數來表示應該替代的類型。
class SomeClass<T1, T2>where T1:System.Type
where T2:System.Object
//T1,T2 為類型參數
{
public T1 SomeValue = T1;
public T2 SomeObject = new T2();
}
上面是泛型類的一種抽象實現。,這里出現了where,它是泛型中的約束。
約束
對于第一個我們定義的泛型棧來說,它對所有類型參數都只是做了Push和Peek的操作,并沒用到項本身的運算符的事情。但在我們的實際情況下,我們不得不去訪問處理一些類型的對象,這時,如果不去約束的話往往編譯時會報錯。
要讓泛型變得更有用,我們需要提供額外的信息讓編譯器知道參數可以接受哪些類型。這些額外的信息叫做約束。
約束使用where子句列出。
-每一個約束有約束的類型參數有自己的where字句
-如果形參有多個約束,它們在where字句中使用逗號分隔。
where TypeParam : constraint , constraint, ...
class MyClass<T1,T2,T3> where T2 : Customer
where T3 : IComparable
{
....
}