C# 知識體系構建(二)| C# 1.0 上

2021-01-12 小小Unity

從這一篇開始,我們就正式開始構建C#的知識體系。我們先羅列一下C# 1.0發布時所包含的語法特性,如下:類(Class)

結構(Struct)

接口(Interface)

事件(Event)

屬性(Property)

委託(Delegates)

表達式

語句

特性(有時候也叫屬性)(Attribute)

C# 1.0的特性只有以上這些,基本上涵蓋了C#中最常用、最核心、最基礎部分的內容。有了以上這些特性,C# 1.0就足夠我們去寫一些應用程式了。

對於有點經驗的同學來說,以上的這些特性:除了結構(Struct)和事件(Event),大家都應該很熟悉了,最起碼在寫項目的時候都有接觸過。由於本文是比較偏向C#使用進階的,一些非常基礎的東西就不做過多地介紹了。

接下來,我們開始按順序簡單地過一下以上的特性。

2.1 我所理解的類(一)

單純從功能上來說,類可以:

一提到類,第一時間想到的就是以上的這些功能。

往細了想,類還提供了很多的功能,不過這些都不是本文的重點。重點是,編程中有沒有類有什麼區別?

2.1.1 沒有類會怎麼樣?

如果沒有類,在Unity中就無法方便地寫腳本,因為Unity中的腳本需要繼承MonoBehaviour類。

我們知道MonoBehaviour中包含了Transform、GameObject的引用,也有一些生命周期方法,比如:Awake、Start、Update、OnDestory、OnEnable、OnDisable、OnTriggerEnter等,提供了豐富的功能和API。

我們寫Unity腳本的時候,只需要簡單地繼承MonoBehaviour類就可以擁有以上所說的所有功能和API。也就是說類的繼承這個功能,讓用戶可以更方便地復用代碼,更方便地使用引擎。

以上僅僅是一個小例子,大家可以從自己的編程經驗出發,簡單思考下沒有類會怎麼樣?

2.1.2 類是編程生涯中的一個裡程碑

早期,我們在學習一門語言的時候會接觸到一門語言的各種特性和概念。類這個概念,是比較容易接觸到、也比較容易理解的概念。但是並不是接觸過了、理解了就代表能夠使用了。

記得在學校的時候,我先後接觸了Java、Android、Objective-C、Cocos2D/Cocos2D-x、C++ 等平臺和語言。Java與Java Web學習了有半年,然後開始著手做一些學校的項目。後來接觸了Android,也做了半年。等到接觸Objective-C和Cocos2D的時候已經是大三了,當時距離我寫下第一行代碼已經過去了兩年,但是寫的代碼還是很混亂。

現在看來,亂的原因非常簡單,就是不會分類。

比如:在寫Android的時候,我會把很多代碼都寫到一個文件裡,也就是Android工程創建時自帶的Activity類(Activity算是界面類),寫著寫著很容易混亂。在寫Cocos2D項目的時候,也習慣把很多代碼寫到一個Scene類裡,不管是播放動畫,還是輸入監聽,全部都在同一個Scene類裡聲明方法並實現。

直到某天,由於實在過於混亂,於是決定自己試著把一些邏輯寫在一些類裡,把邏輯分出去,交給其它的類負責,這是我第一次有分類的意識。從寫下第一行代碼到這個時候,已經過去兩年多的時間了,這兩年多的時間做的項目都是小項目,簡單的Android App、簡單的網站、簡單的小遊戲(對對碰、2048)等等,沒法做一些體量更大的項目。

在初次嘗試分類之後,編程之路就順了一些,雖然項目到最後還是會混亂,不過已經能寫一些三消、跑酷、爬塔之類的遊戲了(體量不大,但是對一個大學生來說是個挑戰)。所以說,開始分類是我編程生涯的一個裡程碑。

分類不用做得非常好,只需要開始做,就可以得到非常大的回報。對於工作多年的人來說,分類應該不難,但如果是剛接觸編程不久的同學,分類也許是一個可以讓你突破瓶頸的開始。

開始分類之前,我是一個編程初學者,歷時兩年,這段期間寫出來的東西很混亂,一度覺得自己不適合做開發者,一直很沒自信。開始分類之後,我算初級開發者,從一開始,把邏輯交給靜態類的靜態方法,到之後慢慢把邏輯交給一些對象負責,編程能力在慢慢提高,做出來的項目的規模也在逐步擴大。

2.1.3 小結

類可以繼承、包含屬性、包含方法、可以用來創建對象

沒有類,Unity引擎可能沒那麼好用了

分類是筆者編程生涯的一個裡程碑

2.1.4 知識地圖


2.2 我所理解的類(二)2.2.1 面向對象與面向過程

有了類能夠比較容易地進行面向對象編程,沒有類當然也可以做到,只不過沒有那麼容易。

什麼是面向對象編程呢?根據我的理解只有兩個字:建模。建模就是對需要實現的功能或者需要解決的問題建立業務模型。比如:要實現購買商品功能,就需要我們創建商品對象,還要把購買商品的行為歸屬到另一個對象中,這個對象有可能是顧客對象,也有可能是平臺對象,這就是非常典型的面向對象建模案例。

如果是面向過程中的購買商品會是什麼樣的呢?我們也許可以這樣考慮,購買商品前先創建一個購買商品函數,然後函數可能需要調用資料庫,那就再寫一個調用資料庫的函數交給購買商品函數調用,依次類推。

其實要區分面向對象編程與面向過程編程非常容易。面向對象編程是以對象為基礎進行思考的,而面向過程是以功能(函數)為基礎進行思考的,這就是兩者的差別。

2.2.2 面向對象與面向過程是對立的嗎?

不是對立的,面向對象更擅長設計,而面向過程更擅長實現。在使用C#的時候,這兩種編程思維都會用到。

2.2.3 沒有類如何面向對象編程?

面向對象編程,就需要有對象,如果沒有類,其實也可以實現面向對象編程。C語言雖然不支持類,但是也可以通過宏或者一些模擬的手段支持類和對象;Lua語言也沒有提供類功能,但是通過元表也能夠模擬類和對象。總之,面向對象編程的核心就是兩個字:建模。

2.2.4 知識地圖:

2.3 我所理解的類(三)

簡單說了一下面向對象和面向過程這兩個概念。現在來講一下引用類型和值類型這個話題。

2.3.1 引用類型和值類型

幾乎在每一本程式語言書籍上都會談到引用類型和值類型這兩個概念,具體的引用類型和值類型相關的細節,大家可以在網上找各種文章。

這裡先給出我的理解:引用類型,是用類創建的類型就是引用類型。值類型包含基礎類型和結構體(Struct)創建出來的類型。如下:

2.3.2 定義

值類型直接存儲其值,而引用類型存儲對其值的引用。

值類型和引用類型是非常重要但非常基礎的話題,所以想深入研究,網上能夠找到足夠多的文章。在這裡僅僅是強調一下重要性,具體細節就不浪費篇幅了。

2.3.3 類是引用類型

記住這句話就足夠了。

2.3.4 知識地圖

2.4 我所理解的類(四)
2.4.1 剩下的一些關鍵特性和功能

前面我們聊了一些關於類的話題,如下:

類的功能

類在編程生涯中的作用

面向對象和面向過程

值類型和引用類型

除了以上這些話題,還有很多其它話題,如下:

類的訪問權限(封裝性)

類的命名

抽象類與接口(繼承性、多態性)內部類

Partial關鍵字

泛型類

等等

在這裡不會深入介紹這些內容,但接下來會簡單瀏覽一下。

2.4.2 類的訪問權限

訪問權限有:Internal、Private、Public。Internal Class一般在打DLL的時候作用很大,可以控制有些類不讓用戶訪問到。Private Class用得不多,一般作為內部類存在。

如果不知道Internal是什麼作用,可以在評論區提問。

2.4.3 類的命名

起名要合適,類的命名一般是名詞。

2.4.4 抽象類與接口

抽象類中有的時候需要些抽象方法,抽象方法需要在子類中覆寫。實現接口可以顯式實現和隱式實現,顯式實現可以控制方法的訪問權限,這個在接口的部分會仔細講解。

2.4.5 內部類

有的時候需要在類內部創建一些只需要在類內部使用的對象,這時候可以用內部類。

2.4.6 Partial關鍵字

Partial可以實現將類的邏輯拆分到不同的文件。

2.4.7 泛型類

類需要適配不同的類型的時候,可以用泛型類,比如單例的模板。

到此就簡單說了一些類相關的特性,只需要讀一遍有個印象即可,如果遇到不懂的部分,可以在評論區留言,也可以自行搜索。

2.4.8 知識地圖


2.5 結構體

說到結構體,第一時間想到的就是:結構體是值類型。值類型具體是什麼樣的呢?

不知道大家記不記得Unity中有Vector3、Vector2這樣的向量類型,我們接觸Vector3比較多的地方是transform.position和transform.localPosition。在剛開始接觸 transform.position和transform.localPosition的時候,會對一件事情產生深刻印象。就是如果我想給一個Transform的x坐標賦值,代碼如下:

  

 var position = transform.position;    position.x = 1.0f;    transform.position = position;


一個簡單的賦值代碼,需要寫三行。如果覺得很麻煩,可以這樣寫:

transform.position.x = 1.0;


這樣寫會方便很多。這是因為Position的類型Vector3是Struct類型,Struct是值類型,同時Position是Transform的一個屬性(而不是成員變量),所以就必須要給整個 Position變量賦值,而不是Position變量中的某一個變量。

這就是Struct和Class最明顯的區別:作為一個屬性時,Struct無法對單一的成員變量賦值,而Class則是只要允許可以隨便賦值。

關於結構體,其實有很多細節可以進行學習,但是我們不用學那麼多。根據我自己的經驗,結構體只需要知道如下關鍵點就行了:

除了以上五點比較重要之外,在其它情況下,很少用到結構體。我從以前到現在,接觸到和結構體相關的編碼實踐也僅限於以上的五點特性。但是肯定還有很多其它的特 性,雖然也許不那麼常用,但是在這裡我們也可以簡單地過一遍。

2.5.1 其它的細節

在結構聲明中,除非將欄位聲明為const或static,否則無法初始化。

結構不能聲明無參數構造函數(沒有參數的構造函數)或終結器。

結構在分配時進行複製。將結構分配給新變量時,將複製所有數據,並且對新副本所做的任何修改不會影響原始副本的數據。在處理值類型的集合(如 Dictionary)時,請務必記住這一點。

結構是值類型,不同於類,類是引用類型。

與類不同,無需使用new運算符即可對結構進行實例化。

結構可以聲明具有參數的構造函數。

一個結構無法繼承自另一個結構或類,並且它不能為類的基類。所有結構都直接繼承自ValueType,後者繼承自Object。

結構可以實現接口。

結構不能為null,並且不能向結構變量分配null,除非將變量聲明為可為空的值類型

2.5.2 知識地圖


相關焦點

  • 卓越密碼:個人知識體系構建培訓提綱
    該課程以《卓越密碼:如何成為專家》為基礎材料,主要講述高效學習方法和個人知識體系構建的過程,並通過現場練習的方式使學員掌握形成知識體系過程中所需要的能力。建議上課前已閱讀過《卓越密碼:如何成為專家》。當前該課程主要以內訓方式組織。
  • Visual Studio 2019 v16.8 和 v16.9 Preview 1 發布
    現在可直接從 Visual Studio 在遠程 Linux 系統或 WSL 上調試 Linux 核心轉儲。另外關於 Linux,新版本還改進了錯誤報告。通過在「項目屬性」窗口中選擇「啟用 .NET 分析器」,可以針對 .NET 5.0 之前的版本上的項目啟用代碼分析。 內聯參數名稱提示。
  • API 測試工具 Hitchhiker v0.7,Schedule 的對比 diff
    新年的第一個更新:1.
  • 阿里巴巴 canal 開源組件發布 v1.1.3 版本
    基於 canal 的準實時日誌訂閱消費,你可以完成類似的業務: 同步到另一個資料庫,比如異地容災、同步離線庫等 構建多級索引 (賣家和買家各自分庫索引) 實時構建搜尋引擎,比如同步給 elasticsearch 業務 cache 刷新 價格變化等重要業務消息項目開源地址:https://github.com/alibaba/canal。
  • C#與人工智慧(第4講)創建樸素貝葉斯分類器
    #人工智慧#本文先實現一個簡單的貝葉斯分類器,輸入二進位,判斷0-7。後續文章會講述它的高級應用——貝葉斯推理機。C#與人工智慧(第3講)創建神經網絡C#與人工智慧(第2講)創建WinForm程序C#與人工智慧(第1講)安裝C#編程環境託馬斯·貝葉斯是18世紀英國數學家,概率論、貝葉斯統計的創立者。
  • 輕鬆實現Java與C#時間轉換
    1日起的到當前的毫秒的數。關於Ticks,msdn上是這樣說的: A single tick represents one hundred nanoseconds or one ten-millionth of a second.
  • 使用C#的後端Web API:循序漸進教程
    上。哪種語言最受歡迎?你應該使用哪一個?也許有人會推薦PHP,它具有豐富的功能和較低的學習曲線。然而,事實仍然是現在最常用的語言是Java和.NET。本教程介紹如何使用C#(ASP.NET)構建自己的Web伺服器(Web API)。重要的是要注意,要託管您的伺服器,您將需要基於Windows的託管。
  • 研究生導師立德樹人職責履行評價指標體系的構建
    一、相關研究現狀  (一)研究生導師立德樹人職責履行評價指標體系的相關研究  文獻檢索發現,關於研究生導師立德樹人職責評價指標體系的研究僅有兩篇密切相關文獻。曹洪軍、王娜從工作結果與工作過程兩大維度出發,構建了「二三三」考評指標體系。
  • C#如何使用定時器[Timer]
    在新程序界面空白窗口上放置合適的控制項:包括,顯示操作流程的textbox控制項;用於時間間隔秒數的輸入框;開始計時器按鈕和停止計時器的按鈕;timer控制項。添加變量設置標誌位, 如果為0 停止計時, 如果為1 則開始計時;設置臨時變量;設置變量,獲取指定的間隔秒數。添加按鈕【開始】代碼獲取指定的間隔秒數;設置臨時變量;設置標誌位為開始。
  • C# 16進位轉換10進位相關函數詳解
    2 1、位邏輯非運算 位邏輯非運算是單目的,只有一個運算對象。位邏輯非運算按位對運算對象的值進行非運算,即:如果某一位等於0,就將其轉變為1;如果某一位等於1,就將其轉變為0。 比如,對二進位的10010001進行位邏輯非運算,結果等於01101110,用十進位表示就是:~145等於110;對二進位的01010101進行位邏輯非運算,結果等於10101010。用十進位表示就是~85等於176。
  • 解析|如何構建知識圖譜
    二、舉個例子 如果說,目前的感覺還不是很直觀的話,讓我們來一起接受一項知識圖譜的構建任務: 1.任務場景 現在,一家企業求助到你,通過與他進行深度訪談和業務調研,企業面臨著以下幾點問題: 1)企業人員流動性高,包括新員工和培養了一段時間的經驗員工,人員流動的背後,代表著工作經驗、知識沉澱的流失,需要耗費更多的精力去做好整理和傳承工作; 2)企業知識紛繁複雜,關於工作的相關知識內容,尚未形成體系
  • 在unity中用C#連接資料庫步驟
    首先打開unity目錄,找到I18N.dll I18N.West.dll I18N.CJK.dll 如果不引用這三個,在測試的時候也可以連上,但是打包出來就連不上了!!!這個坑歐陽始終記得。然後在 D:\Program Files\Unity\Editor\Data\Mono\lib\mono\2.0找到System.Data.dll System.Drawing.dll這樣,驅動包導入成功。接下來開始寫代碼測試。新建一個MyLogin腳本。