C# 語言入門基礎介紹

前言:

C#(讀作“See Sharp”)是一種新式編程語言,不僅面向對象,還類型安全。 開發人員利用 C# 能夠生成在 .NET 中運行的多種安全可靠的應用程序。 C# 源於 C 語言系列,C、C++、Java 和 JavaScript 程序員很快就可以上手使用。 本教程概述瞭 C# 8 及更高版本中該語言的主要組件。

C# 是面向對象的、面向組件的編程語言。 C# 提供瞭語言構造來直接支持這些概念,讓 C# 成為一種非常自然的語言,可用於創建和使用軟件組件。 自誕生之日起,C# 就添加瞭支持新工作負載和新興軟件設計實踐的功能。 C# 本質上是面向對象的語言。_* 你需要定義類型及其行為。

多項 C# 功能有助於創建可靠且持久的應用程序。 垃圾回收自動回收不可訪問的未用對象所占用的內存。 可以為 null 的類型可防范不引用已分配對象的變量。 異常處理提供瞭一種結構化且可擴展的方法來進行錯誤檢測和恢復。 Lambda 表達式支持函數編程技術。 語言集成查詢 (LINQ) 語法創建一個公共模式,用於處理來自任何源的數據。 異步操作語言支持提供用於構建分佈式系統的語法。 C# 有統一類型系統。 所有 C# 類型(包括 int double 等基元類型)均繼承自一個根 object 類型。 所有類型共用一組通用運算。 任何類型的值都可以一致地進行存儲、傳輸和處理。 此外,C# 還支持用戶定義的引用類型和值類型。 C# 允許動態分配輕型結構的對象和內嵌存儲。 C# 支持泛型方法和類型,因此增強瞭類型安全性和性能。 C# 可提供迭代器,使集合類的實現者可以定義客戶端代碼的自定義行為。

C# 強調版本控制,以確保程序和庫以兼容方式隨時間推移而變化。 C# 設計中受版本控制加強直接影響的方面包括:單獨的 virtual override 修飾符,關於方法重載決策的規則,以及對顯式接口成員聲明的支持。

一、.NET 體系結構

C# 程序在 .NET 上運行,而 .NET 是名為公共語言運行時 (CLR) 的虛執行系統和一組類庫。 CLR 是 Microsoft 對公共語言基礎結構 (CLI) 國際標準的實現。 CLI 是創建執行和開發環境的基礎,語言和庫可以在其中無縫地協同工作。

用 C# 編寫的源代碼被編譯成符合 CLI 規范的中間語言 (IL)。 IL 代碼和資源(如位圖和字符串)存儲在擴展名通常為 .dll 的程序集中。 程序集包含一個介紹程序集的類型、版本和區域性的清單。

執行 C# 程序時,程序集將加載到 CLR。 CLR 會直接執行實時 (JIT) 編譯,將 IL 代碼轉換成本機指令。 CLR 可提供其他與自動垃圾回收、異常處理和資源管理相關的服務。 由 CLR 執行的代碼有時稱為“托管代碼”。 “非托管代碼”編譯為面向特定平臺的本機語言。

語言互操作性是 .NET 的一項重要功能。 C# 編譯器生成的 IL 代碼符合公共類型規范 (CTS)。 通過 C# 生成的 IL 代碼可以與通過 .NET 版本的 F#、Visual Basic、C++ 生成的代碼進行交互。 還有 20 多種與 CTS 兼容的語言。 單個程序集可包含多個用不同 .NET 語言編寫的模塊。 這些類型可以相互引用,就像它們是用同一種語言編寫的一樣。

除瞭運行時服務之外,.NET 還包含大量庫。 這些庫支持多種不同的工作負載。 它們已整理到命名空間中,這些命名空間提供各種實用功能。 這些功能包括文件輸入輸出、字符串控制、XML 分析、Web 應用程序框架和 Windows 窗體控件。 典型的 C# 應用程序廣泛使用 .NET 類庫來處理常見的“管道”零碎工作。

二、Hello world

“Hello, World”程序歷來都用於介紹編程語言。

下面展示瞭此程序的 C# 代碼:

using System;

class Hello
{
    static void Main()
    {
        Console.WriteLine("Hello, World");
    }
}


“Hello, World”程序始於引用 System 命名空間的 using 指令。 命名空間提供瞭一種用於組織 C# 程序和庫的分層方法。 命名空間包含類型和其他命名空間。例如,System 命名空間包含許多類型(如程序中引用的 Console 類)和其他許多命名空間(如 IO 和 Collections)。 借助引用給定命名空間的 using 指令,可以非限定的方式使用作為相應命名空間成員的類型。 由於使用 using 指令,因此程序可以使用 Console.WriteLine 作為 System.Console.WriteLine 的簡寫。

“Hello, World”程序聲明的 Hello 類隻有一個成員,即 Main 方法。 Main 方法使用 static 修飾符進行聲明。 實例方法可以使用關鍵字 this 引用特定的封閉對象實例,而靜態方法則可以在不引用特定對象的情況下運行。 按照約定,Main 靜態方法是 C# 程序的入口點。

程序的輸出是由 System 命名空間中 Console 類的 WriteLine 方法生成。 此類由標準類庫提供。默認情況下,編譯器會自動引用標準類庫。

三、類型和變量

類型定義 C# 中的任何數據的結構和行為。 類型的聲明可以包含其成員、基類型、它實現的接口和該類型允許的操作。 變量是用於引用特定類型的實例的標簽。

C# 有兩種類型:值類型 和 引用類型。 值類型的變量直接包含它們的數據。 引用類型的變量存儲對數據(稱為“對象”)的引用。 對於引用類型,兩個變量可以引用同一個對象;對一個變量執行的運算可能會影響另一個變量引用的對象。 借助值類型,每個變量都有自己的數據副本;因此,對一個變量執行的運算不會影響另一個變量(ref 和 out 參數變量除外)。

標識符為變量名稱。 標識符是不包含任何空格的 unicode 字符序列。 如果標識符的前綴為 @,則該標識符可以是 C# 保留字。 在與其他語言交互時,使用保留字作為標識符很有用。

C# 的值類型進一步分為:簡單類型、枚舉類型、結構類型、可以為 null 的值類型和元組值類型。 C# 引用類型又細分為類類型、接口類型、數組類型和委托類型。

C# 程序使用 類型聲明 創建新類型。 類型聲明指定新類型的名稱和成員。 用戶可定義以下六種 C# 類型:類類型、結構類型、接口類型、枚舉類型、委托類型和元組值類型。 還可以聲明 record 類型(record struct record class)。 記錄類型具有編譯器合成成員。 記錄主要用於存儲值,關聯行為最少。

class 類型定義包含數據成員(字段)和函數成員(方法、屬性及其他)的數據結構。 類類型支持單一繼承和多形性,即派生類可以擴展和專門針對基類的機制。
struct 類型定義包含數據成員和函數成員的結構,這一點與類類型相似。 不過,與類不同的是,結構是值類型,通常不需要進行堆分配。 結構類型不支持用戶指定的繼承,並且所有結構類型均隱式繼承自類型 object
interface 類型將協定定義為一組已命名的公共成員。 實現 interface class struct 必須提供接口成員的實現代碼。 interface 可以繼承自多個基接口,class 和 struct 可以實現多個接口。
delegate 類型表示引用包含特定參數列表和返回類型的方法。 通過委托,可以將方法視為可分配給變量並可作為參數傳遞的實體。 委托類同於函數式語言提供的函數類型。 它們還類似於其他一些語言中存在的“函數指針”概念。 與函數指針不同,委托是面向對象且類型安全的。
classstructinterface delegate 類型全部都支持泛型,因此可以使用其他類型對它們進行參數化。

C# 支持任意類型的一維和多維數組。 與上述類型不同,數組類型無需先聲明即可使用。 相反,數組類型是通過在類型名稱後面添加方括號構造而成。 例如,int[] 是 int 類型的一維數組,int[,] 是 int 類型的二維數組,int[][] 是由 int 類型的一維數組或“交錯”數組構成的一維數組。

可以為 null 的類型不需要單獨定義。 對於所有不可以為 null 的類型 T,都有對應的可以為 null 的類型 T?,後者可以包含附加值 null。 例如,int? 是可保存任何 32 位整數或 null 值的類型,string? 是可以保存任何 string 或 null 值的類型。

C# 采用統一的類型系統,因此任意類型的值都可視為 object。 每種 C# 類型都直接或間接地派生自 object 類類型,而 object 是所有類型的最終基類。 隻需將值視為類型 object,即可將引用類型的值視為對象。 通過執行 裝箱 和 取消裝箱操作,可以將值類型的值視為對象。 在以下示例中,int 值被轉換成 object,然後又恢復成 int。

int i = 123;
object o = i;    // Boxing
int j = (int)o;  // Unboxing


將值類型的值分配給 object 對象引用時,會分配一個“箱”來保存此值。 該箱是引用類型的實例,此值會被復制到該箱。 相反,當 object 引用被顯式轉換成值類型時,將檢查引用的 object 是否是具有正確值類型的箱。 如果檢查成功,則會將箱中的值復制到值類型。

C# 的統一類型系統實際上意味著“按需”將值類型視為 object 引用。 鑒於這種統一性,使用類型 object 的常規用途庫可以與派生自 object 的所有類型結合使用,包括引用類型和值類型。

C# 有多種 變量,其中包括字段、數組元素、局部變量和參數。 變量表示存儲位置。 每個變量都具有一種類型,用於確定可以在變量中存儲哪些值,

如下文所述:

不可以為 null 的值類型

  • 具有精確類型的值

可以為 null 的值類型

  • null 值或具有精確類型的值

object

  • null 引用、對任意引用類型的對象的引用,或對任意值類型的裝箱值的引用

類類型

  • null 引用、對類類型實例的引用,或對派生自類類型的類實例的引用

接口類型

  • null 引用、對實現接口類型的類類型實例的引用,或對實現接口類型的值類型的裝箱值的引用

數組類型

  • null 引用、對數組類型實例的引用,或對兼容的數組類型實例的引用

委托類型

  • null 引用或對兼容的委托類型實例的引用

四、程序結構

C# 中的關鍵組織結構概念包括程序、命名空間、類型、成員和程序集* 。 程序聲明類型,而類型則包含成員,並被整理到命名空間中。 類型示例包括類、結構和接口。 成員示例包括字段、方法、屬性和事件。 編譯完的 C# 程序實際上會打包到程序集中。 程序集的文件擴展名通常為 .exe 或 .dll,具體視其分別實現的是應用程序還是庫_***而定。

作為一個小示例,請考慮包含以下代碼的程序集:

namespace Acme.Collections;

public class Stack<T>
{
    Entry _top;

    public void Push(T data)
    {
        _top = new Entry(_top, data);
    }

    public T Pop()
    {
        if (_top == null)
        {
            throw new InvalidOperationException();
        }
        T result = _top.Data;
        _top = _top.Next;

        return result;
    }

    class Entry
    {
        public Entry Next { get; set; }
        public T Data { get; set; }

        public Entry(Entry next, T data)
        {
            Next = next;
            Data = data;
        }
    }
}

此類的完全限定的名稱為 Acme.Collections.Stack

 此類包含多個成員:一個 _top 字段、兩個方法(Push 和 Pop)和一個 Entry 嵌套類。 Entry 類還包含三個成員:一個名為 Next 的屬性、一個名為 Data 的屬性和一個構造函數。 Stack 是泛型類。 它具有一個類型參數 T,在使用時替換為具體類型。

堆棧是一個“先進後出”(FILO) 集合。 添加到堆棧頂部的新元素。 刪除元素時,將從堆棧頂部刪除該元素。 前面的示例聲明定義堆棧的存儲和行為的 Stack 類型。 可以聲明一個引用 Stack 類型的實例的變量來使用該功能。

程序集包含中間語言 (IL) 指令形式的可執行代碼和元數據形式的符號信息。 執行前,.NET 公共語言運行時的實時 (JIT) 編譯器會將程序集中的 IL 代碼轉換為特定於處理器的代碼。

由於程序集是包含代碼和元數據的自描述功能單元,因此無需在 C# 中使用 #include 指令和頭文件。 隻需在編譯程序時引用特定的程序集,即可在 C# 程序中使用此程序集中包含的公共類型和成員。

例如,此程序使用 acme.dll 程序集中的 Acme.Collections.Stack 類:

class Example
{
    public static void Main()
    {
        var s = new Acme.Collections.Stack<int>();
        s.Push(1); // stack contains 1
        s.Push(10); // stack contains 1, 10
        s.Push(100); // stack contains 1, 10, 100
        Console.WriteLine(s.Pop()); // stack contains 1, 10
        Console.WriteLine(s.Pop()); // stack contains 1
        Console.WriteLine(s.Pop()); // stack is empty
    }
}


若要編譯此程序,需要引用包含前面示例中定義的堆棧類的程序集。

C# 程序可以存儲在多個源文件中。 在編譯 C# 程序時,將同時處理所有源文件,並且源文件可以自由地相互引用。 從概念上講,就好像所有源文件在被處理之前都連接到一個大文件。 在 C# 中永遠都不需要使用前向聲明,因為聲明順序無關緊要(極少數例外情況除外)。 C# 並不限制源文件隻能聲明一種公共類型,也不要求源文件的文件名必須與其中聲明的類型相匹配。

到此這篇關於C# 語言入門基礎介紹的文章就介紹到這瞭,更多相關C# 語言介紹內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: