標籤:
一,委託
- 委託封裝了包含特殊傳回型別和一組參數的行為,類似包含單一方法介面。
- 委託型別宣告中所描述的類型簽名決定了哪個方法可以用於建立委託執行個體,同時決定了調用的簽名:委託類型實際上只是參數類型的一個列表以及一個傳回型別
- 建立委託執行個體,需要一個方法已經調用該方法的目標:
void Invoke(string input)具有個委託相同的類型和相同的參數
- 委託執行個體不易變形: 委託是不易變的。委託執行個體就和string一樣。Delegate.Combine和string.Concat很像,都是合并現有的執行個體形 成一個新執行個體
- 每個委託執行個體都包含一個調用列表——一個巨集指令清單:
委託執行個體還有一個調用列表與之關聯,如:
- 委託執行個體可以合并到一起,也可以從委託執行個體中刪除另一個
- 事件不是委託執行個體,只是成對的add/remove方法(類似屬性的取值和賦值)
delegate void StringProcessor(string input);//委託簽名
class Person
{
string name;
public Person(string name)
{
this.name = name;
}
public void Say(string msg)
{
Console.WriteLine("{0}agy:{1}", name, msg);
}
public void tu(string msg)
{
Console.WriteLine("{0}agy:{1}", name, msg);
}
}
#region 委託事件
Person jon = new Person("Jon");
Person tom = new Person("tom");
StringProcessor jons, toms, background;///建立委託執行個體
jons = new StringProcessor(jon.Say);//委託執行個體使用的方法
toms = new StringProcessor(tom.Say);
background = new StringProcessor(Backgroud.Note);
jons += toms;
jons("Hello,jon");
toms("Hello,tom");
background("note");
#endregion
二,類型系統特徵
- C#1是靜態類型的——編譯器知道你能使用哪些成員:每個變數都有一個特並的類型,而且該類型在編譯時間是已知的,只有該類型已知的操作才被允許。
- C#1是顯示的——必須告訴編譯器變數具有什麼類型:每個變數的類型必須在聲明的時候指定。
- C#1是安全的——除非存在真實的轉換關係,否則不能把一個類型當作另一個類型使用。(在完全無關的結構之間進行強制類型轉換,很容易造成嚴重的後果)
- 靜態類型不予許一個集合成為強型別的“字串列表”或者“整數列表”,除非針對不同的元素使用大量重複代碼:數組是強型別的,所以不可能將一個string[]的一個元素設定成一個FileStream,參考型別數組支援協變,只要元素類型之間允許轉換。
- 方法的覆蓋和實現不允許協變性/逆變性。
“協變”是指能夠使用與原始指定的衍生類別型相比,派生程度更大的類型。
“逆變”則是指能夠使用派生程度更小的類型。
只是有一點記住Dog 繼承自Animal,
所以Dog變成Animal 就是和諧的變化(協變),而如果Animal 變成Dog就是不正常的變化(逆變)
三,實值型別和參考型別
- 對於參考型別的運算式(變數),它的值是一個引用,而非對象:
- 引用就像URL——允許你訪問真實資料的一小片資料。
- 對於實值型別的運算式,它的值是實際資料。
- 參考型別的對象總是在堆上,實值型別的值既可以在棧上也可能在堆上,具體取決於上下文:變數的值在它聲明的位置儲存,在一個類中有一個int類型的執行個體變數,那麼這個int的值就和對象中其他資料在一起,也就是堆中。
- 參考型別的值作為方法參數使用是,參數預設是以“值傳遞”——但值得本身是一個引用。
- 實值型別的值會在需要參考型別的行為的時候被裝箱,反之,則拆箱:當一個實值型別調用Tostring,Equals或GetHashCode方法時,如果該類型沒有覆蓋這些方法,也會發生裝箱。盡量少用拆箱和裝箱,當大量操作時,這會影響效能。
四,動態類型
dynamic d = "hello";//動態類型
Console.WriteLine(d.Length);
d = new string[] { "hi", "there" };
Console.WriteLine(d.Length);
C#1所搭建的核心基礎