C# 高級語法特性(一)
打算持續(xù)更新一個(gè)專欄,旨在分享對C#這門編程語言的理解,鞏固自己的C#知識體系以用于之后可能的Unity游戲開發(fā)(所以我對C#的討論會更多地基于它在Unity這個(gè)游戲引擎的實(shí)際應(yīng)用),并討論一些C#區(qū)別于其它語言的特點(diǎn)。既然是針對于C#,自然不涉及太多各語言都包含的語法知識和面向?qū)ο蠡A(chǔ),更多會討論一些進(jìn)階知識,整理C#的高級語法特性,故該專欄可能不適用于編程新手。其中可能會總結(jié)一些其他書籍、課程中分享的經(jīng)驗(yàn),甚至部分搬運(yùn)到專欄中來。對文章中可能出現(xiàn)的任何錯(cuò)誤和紕漏,歡迎大家指出和糾正。

Unity對C#版本的支持
Unity 4.x 支持到 C# 2.0
Unity 5.x 支持到 C# 3.0,
Unity 2017.x 支持到 C# 6.0
Unity 2018.x 到 C# 7.2
????C#和其它語言一樣,自然也經(jīng)歷過版本的迭代,而編程語言的第一版一般都是核心部分,也是最常用的部分。
C# 1.0
羅列一下1.0版本中的語法特性:
類(class)
結(jié)構(gòu)(struct)
接口(interface)
屬性(property)
事件(event)
委托(delegates)
表達(dá)式
語句
特性(屬性)(Attribute)
類
????大概會涉及到面向?qū)ο缶幊陶Z言中共有的一些話題如:訪問權(quán)限、抽象類、內(nèi)部類、繼承多態(tài)等,就無需過多介紹了。提一下C#中一個(gè)特殊的關(guān)鍵字partial,其實(shí)也很簡單,它可以實(shí)現(xiàn)類的邏輯拆分到不同的文件。
結(jié)構(gòu)
????熟悉C或者C++的開發(fā)者可能會對結(jié)構(gòu)體比較熟悉,C#中也有結(jié)構(gòu)體這個(gè)概念,其中最關(guān)鍵的一點(diǎn):值類型。
????在Unity開發(fā)中,我們要對一個(gè)游戲?qū)ο蟮奈恢眠M(jìn)行改變時(shí),不得不寫成如下形式:
????Vector3 pos?= transform.position;?
????pos.x = 2.0f;?
????transform.position = pos;
????而不是
????transform.position.x = 2.0f;
????在這里,無法直接對結(jié)構(gòu)體中的單一變量賦值??偨Y(jié)C#結(jié)構(gòu)體的一些關(guān)鍵點(diǎn):
值類型
結(jié)構(gòu)不能為null
聲明變量時(shí),本身就有值了
分配給新變量時(shí),是深拷貝,并且對新副本所做的任何修改不會更改原始副本的數(shù)據(jù)
在為屬性器時(shí),不能局部賦值
接口
????接口需要提一點(diǎn):顯式實(shí)現(xiàn)和隱式實(shí)現(xiàn)。顯式實(shí)現(xiàn)在Unity中其主要的應(yīng)用場景是防止誤調(diào)用,如:
????public interface ITask { ? ?
????????void?Run(); ? ?
????}
????public class?Task : ITask{
????????void ITask.Run(){
????????????...
????????}
????public class TaskRunner{ ? ?
????????public static void RunTask(ITask task){ ? ? ? ?
????????????task.Run(); ? ? ? ?
????????}?
????}
????void Start(){ ? ?
????????var task = new Task();
????????// task.Run(); 顯式實(shí)現(xiàn),無法直接調(diào)用
????????TaskRunner.RunTask(task); // 用專門的執(zhí)行器去調(diào)用
????}
????接口的顯式實(shí)現(xiàn)降低了方法調(diào)用的權(quán)限,避免開發(fā)者誤調(diào)用。
屬性器
????屬性器的優(yōu)勢在于隔離類內(nèi)部的變化,也體現(xiàn)了OOP的封裝性。如:
????public class A{
????????public int a;??
????}
????此時(shí)在另一處訪問了此屬性:
????void Start(){
????? ?var ob?= new A() { a = 1 }?;
????? ?Debug.Log(ob.a);
????}
????當(dāng)我們需要對屬性a的計(jì)算方法進(jìn)行改變時(shí):
????public class A{
????????public int a{
????????????get{
????????????????return 1 - b ;
????????????}
????????}
????????public int b;
????}
? ??此時(shí)我們只需在聲明處傳入b的值即可,而無需再在訪問屬性a的地方對其進(jìn)行任何更改。

事件、委托、特性會放在下一篇專欄中進(jìn)行總結(jié)。