前面二篇(Action、Func)我們大致上了解了怎麼在開後門,讓外部實做內部的程式碼,但是如果有多個參數的情形呢?
其實這會套用到泛型的概念,而這篇是早在第一篇就該說明了,之所以延到這篇再來講,是希望降低認識委派的門檻,畢竟泛型跟委派是二種不同的概念。
那我們現在來定義一下
Delegate是基底型別,而Func與Action則是.Net預先定義好Delegate型別,二者差異在於有無返回值罷了,應該對於Delegate有了初步的理解吧。
那泛型又是什麼呢?
泛型就是傳入的型別可以是任意型別,那不就是跟dynamic很像嗎?
是的!不過泛型跟dynamic不同之處是前者為編譯時期檢查,後者是執行時期檢查。
泛型的表示方式就是T,如果有多個泛型的表示方式則是<T, T1, T2>依此類推
public void demoT<T, T1, T2>(T t,T1 t1, T2 t2)
{
}
這意思也代表著T可以透過外部傳入型別,亦即外部要傳入什麼型別都可以
// 注意<>括號裡面打什麼
public void demoT<T, T1, T2>(T t, T1 t1, T2 t2)
{
}
public void demo()
{
demoT(1, "1", false);
}
從上述的程式碼可以看到傳任意型別T都能收的到,因此Func<T>即是利用了T的特性,在宣告時,由使用者自行決定參數的型別。
基本上學到這邊可以足夠學會委派了,但泛型的運用不僅於此,如果要學好C#,建議要再搜尋相關資料學習會比較妥當。
如果只是想學習什麼是委派,可以讀到這邊就好,繼續前往下一篇幅。
但如果想要完整的理解幾個名詞的差異,以下建議繼續閱讀
不過即使沒看懂也不會影響,只是未來使用時,會覺得用起來不踏實就是XD
接著我會再說明dynamic、T、var、匿名型別的差別,讓大家對這幾個語法有更深一層的認識
dynamic:
由於dynamic是執行時期進行型別檢查,對於編譯器來說根本就不知道會有哪些屬性、函式可以使用,因此無法享有編譯器給予語法提示的好處,但是,若是知道執行時期會有的屬性、函式,是可以透過該屬性直接取用資料的。
但為什麼要有dynamic呢?
1.在無法精確判斷數值的時候,例如傳進的參數可能是int、double,以及需要高精準度的資料,就適合使用
2.匿名型別的需求,匿名型別是一種編譯時期動態建立物件的方式。由於編譯時期宣告的物件在C#中並不存在,因此沒有型別可以在等號左邊來儲存,進而衍伸出了dynamic的動態建立的方式
var A = new { A ="A" };
可以在編譯器中把滑鼠移到var A看看型別是什麼。看到這邊應該了解什麼是dyanmic了
緊接著為什麼我是用var宣告呢?
其實這段是可以用dynamic的,但為什麼特地用var宣告呢?
因為許多人搞不清楚var、dynamic的差異,所以我特地提出來,希望能讓大家更進一步的理解。
請先在編譯器輸入這段Code
dynamic dynamicStr = "";
var varStr = "";
再把滑鼠移到dynamicStr看看型別
再把滑鼠移到varStr看看型別
可以得知dynamicStr的型別不變,而varStr型別卻是string,為什麼呢?
因為dynamic是動態時型檢查的型別,是個已知型別,而var卻不是型別,而是一種宣告,是透過編譯器 推斷等號(=)右邊的型別
說到這邊應該可以理解dynamic、var、T以及匿名型別的差異了對吧!
T:具有強行別約束的任意型別
dynamic:執行時期動態檢查的型別
var:依據等號右邊型別,而決定型別的宣告式
匿名型別:編譯時期未建立可參考物件時,在動態時期自行生成的物件資料
歡迎您的加入,讓這個社群更加美好!