C# 語法基礎


第一次見到 C# 程序可能會有一些奇怪,程序中有一些 {}[] 這樣的符號。然而在逐漸深入瞭解 C# 語言的過程中,對這些符號和 C# 語言特有的其他符號會越來越熟悉,甚至會喜歡上它們。

本篇,我們繼續從演示一個簡單的程序示例開始,解釋該程序的功能和它的各組成部分。同時,介紹一些 C# 語言的基本語法。

簡單的 C# 程序示例

using System;   /* 告訴編譯器這個程序使用 System 命名空間中的類型 */

namespace ConsoleApp    /* 聲明一個新命名空間,名稱爲 ConsoleApp */
{
    class Program   /* 聲明一個新的類類型,名稱爲 Program */
    {
        /// <summary>
        /// Main 是一個特殊方法,編譯器用它作爲程序的起始點
        /// </summary>
        static void Main()
        {
            int number; /* 聲明一個名爲 number 的變量 */

            // 爲 number 賦值
            number = 1;

            // 輸出一行文字
            Console.WriteLine("C# 語法基礎");

            // 還是輸出一行文字
            Console.WriteLine($"變量 number 的值是:{number}");
        }
    }
}

輸出

C# 語法基礎
變量 number 的值是:1

上面程序中每一行代碼的作用:

第 1 行

告訴編譯器這個程序使用 System 命名空間中的類型

第 3 行

聲明一個新命名空間,名稱爲 ConsoleApp

  • 新命名空間從第 4 行的左大括號({)開始一直延伸到第 24 行與之對應的右大括號(})結束
  • 在這部分裏聲明的任何類型都是該命名空間的成員
第 5 行

聲明一個新的類類型,名稱爲 Program

  • 任何在第 6 行和第 23 行的兩個大括號中間聲明的成員都是組成這個類的成員
第 10 行

聲明一個名稱爲 Main 的方法

  • Main 是一個特殊方法,編譯器用它作爲程序的起始點
第 12 行

聲明一個名爲 number 的變量

第 15 行

number 賦值

第 18 行和第 21 行

輸出一行文字

關於 C# 的語法,要介紹的內容有很多,我們從簡單的開始。

關鍵字

爲了使編譯器能夠解釋代碼,C# 中的某些單詞具有特殊地位和含義,它們稱爲關鍵字。關鍵字是預定義的保留標識符,對編譯器有特殊意義。在上面的代碼中,classstaticvoid 均是關鍵字。

編譯器根據關鍵字識別代碼的結構與組織方式。由於編譯器對這些單詞有着嚴格的解釋,所以必須將關鍵字放在特定位置。如違反規則,編譯器會報錯。

C# 關鍵字列表

- - -
abstract as base
break byte case
char checked class
continue decimal default
do double else
event explicit extern
finally fixed float
foreach goto if
in int interface
is lock long
new null object
out override params
protected public readonly
return sbyte sealed
sizeof stackalloc static
struct switch this
true try typeof
ulong unchecked unsafe
using using static virtual
volatile while

C# 上下文關鍵字列表

上下文關鍵字用於在代碼中提供特定含義,但它不是 C# 中的保留字。 一些上下文關鍵字(如 partialwhere)在兩個或多個上下文中有特殊含義。

- -
add alias
async await
descending dynamic
from get
group into
let nameof
orderby partial(類型)
remove select
unmanaged(泛型類型約束) value
when(篩選條件) where(泛型類型約束)
yield

標識符

標識符是一種字符串,開發者用來命名如變量、方法、參數和許多後面將要闡述的其他程序結構。有效標識符必須遵循以下規則:

  • 不得將關鍵字用作標識符。
  • 標識符必須以字母 a-z A-Z 或下劃線 _ 符號開頭。
  • 標識符可以包含字母 a-z A-Z,數字 0-9 和下劃線 _ 符號。
  • 標識符不得包含任何特殊字符(例如!@ $ *.’[]等),除了下劃線 _
  • 關鍵字附加“@”前綴可作爲標識符使用,例如:可命名局部變量 @return 類似地,可命名方法 @throw()

選擇簡潔而有意義的名稱,這使代碼更容易理解和重用。要選擇清晰(甚至是詳細)的名稱,尤其是在團隊中工作,或者開發要由別人使用的庫的時候。

標識符區分大小寫。例如,變量名 myVarMyVar 是不同的標識符。舉個例子,在下面的代碼片段中,變量的聲明都是有效的,並聲明瞭不同的整型變量。但使用如此相似的名稱會使代碼更易出錯並更難調試,後續需要調試代碼的人會很不爽。

// 語法上有效,但非常混亂
int totalCycleCount;
int TotalCycleCount; 
int TotalcycleCount;

標識符的大小寫規則

標識符有兩種基本的大小寫風格:

  • PascalCasing
  • camelCasing

PascalCasing 約定用於除參數名稱之外的所有標識符,將每個單詞的第一個字符大寫(包括超過兩個字母的首字母縮寫),如以下示例所示:

PropertyDescriptor

HtmlTag (在 HtmlTag 中, 由於首字母縮寫詞 HTML 的長度超過兩個字母,所以僅首字母大寫。)

這裏有一種特殊情況,即遇到兩個字母的首字母縮略詞時,兩個字母都要大寫,如下面的標識符所示:

IOStream

camelCasing 約定僅用於參數名稱,將除第一個單詞之外的每個單詞的第一個字符大寫,如以下示例所示。 該示例還顯示,以 camelCasing 標識符開始的雙字母縮寫詞都是小寫的。

propertyDescriptor

ioStream

htmlTag

標識符命名規範

  • 要更注重標識符的清晰而不是簡短。
  • 不要在標識符名稱中使用單詞縮寫。
  • 不要使用不被廣泛接受的首字母縮寫詞,即使被廣泛接受,非必要也不要用。
  • 不要使用下劃線來區分單詞,也不要在標識符中的任何位置使用下劃線。

參考微軟官方“框架設計準則”,鏈接地址:https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/

類型定義

C# 所有代碼都出現在一個類型定義的內部,最常見的類型定義以關鍵字 class 開頭。

類型名稱(本例是 Program)可以隨便取,但根據約定,它應當使用 PascalCase 風格。就本例來說,可選擇的名稱包括 GreetingsHelloInigoMontoyaHello 或者簡單地稱爲 Program

class Program
{
    // ...
}

Main 方法

Main 方法是 C# 應用程序的入口點。 (庫和服務不要求使用 Main 方法作爲入口點)。Main 方法是應用程序啓動後調用的第一個方法。

static void Main()
{
    // ...
}

C# 要求 Main 方法返回 voidint, 而且要麼無參,要麼接收一個字符串數組。

static int Main(string[] args)
{
    // ...
    return 0;
}

args 參數是用於接收命令行參數的字符串數組,用 System.Environment.CommandLine 獲取執行程序所用的完整命令。

Main 返回的 int 是狀態碼,標識程序執行是否成功。返回非零值通常意味着錯誤。

雖然 Main 方法聲明可進行某種程度的變化,但關鍵字 static 和方法名 Main 是始終都是需要的。以下是有效 Main 示例:

static void Main() { }
static int Main() { }
static void Main(string[] args) { }
static int Main(string[] args) { }
static async Task Main() { }
static async Task<int> Main() { }
static async Task Main(string[] args) { }
static async Task<int> Main(string[] args) { }

花括號、方法體和代碼塊

{
    ...
}

一般來說,所有的 C# 方法都使用花括號標記方法體的開始和結束。這是規定,不能省略。只有花括號({})能起這種作用,圓括號(())和方括號([])都不行。

花括號還可用於把方法中的多條語句合併爲一個單元或塊。

語句和語句分隔符

語句是描述一個類型或告訴程序去執行某個動作的一條源代碼指令,C# 通常用分號標識語句結束。每條語句都由代碼要執行的一個或多個行動構成。聲明變量、控制程序流程或調用方法,所有這些都是語句的例子。

例如,下面的代碼是一個由兩條簡單語句組成的序列。第一條語句定義了一個名稱爲 var1 的整型變量,並初始化它的值爲 5。第二條語句將變量 var1 的值打印到屏幕窗口。

int var1 = 5;
System.Console.WriteLine("The value of var1 is {0}", var1);

語句可以是以分號結尾的單行代碼,也可以是語句塊中的一系列單行語句。 語句塊括在括號 {} 中,並且可以包含嵌套塊。 以下代碼演示了兩個單行語句示例和一個多行語句塊:

namespace ConsoleApp
{
    class Program
    {
        static void Main()
        {
            // Declaration statement.
            int counter;

            // Assignment statement.
            counter = 1;

            // Error! This is an expression, not an expression statement.
            // counter + 1; 

            // Declaration statements with initializers are functionally
            // equivalent to  declaration statement followed by assignment statement:         
            int[] radii = { 15, 32, 108, 74, 9 }; // Declare and initialize an array.
            const double pi = 3.14159; // Declare and initialize  constant.          

            // foreach statement block that contains multiple statements.
            foreach (int radius in radii)
            {
                // Declaration statement with initializer.
                double circumference = pi * (2 * radius);

                // Expression statement (method invocation). A single-line
                // statement can span multiple text lines because line breaks
                // are treated as white space, which is ignored by the compiler.
                System.Console.WriteLine("Radius of circle #{0} is {1}. Circumference = {2:N2}",
                    counter, radius, circumference);

                // Expression statement (postfix increment).
                counter++;

            } // End of foreach statement block
        } // End of Main method body.
    } // End of SimpleStatements class.
}

由於換行與否不影響語句的分隔,所以可將多條語句放到同一行,C# 編譯器認爲這一行包含多條指令。例如,下面的代碼在同一行包含了兩條語句。

int var1 = 5;System.Console.WriteLine("The value of var1 is {0}", var1);

C# 還允許一條語句跨越多行。同樣地,C# 編譯器根據分號判斷語句結束位置。

System
.Console.
WriteLine
("The value of var1 is {0}",
    var1);

空白

程序中的空白指的是沒有可視化輸出的字符,程序員在源代碼中使用的空白將被編譯器忽略。但使代碼更清晰易讀。空白字符包括:空格(Space)、製表符(Tab)、換行符、回車符。

例如,下面的代碼段會被編譯器完全相同地對待而不管它們表面上的區別。

// 推薦的格式
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
}
// 連在一起(不推薦的格式)
class Program {static void Main(string[] args){Console.WriteLine("Hello World!");}}

爲了增強可讀性,用空白對代碼進行縮進很有必要。寫代碼時要遵循制訂好的編碼標準和約定,以增強代碼的可讀性。

註釋

註釋,是代碼中的一些“說明性文字”。註釋本身不會參與程序的編譯和運行,僅僅供程序員閱讀。

註釋分爲:單行註釋、多行註釋、文檔註釋。

單行註釋的符號是 2 條斜線(請注意斜線的方向),2 條斜線右側的內容就是註釋,左側的代碼不會受影響。

多行註釋以“/*”開始,以“*/”結束,之間的內容就是註釋,可以包含多行。

文檔註釋寫在類、方法或屬性,它的符號是 3 條斜線“///”。

/// <summary>
/// XML(文檔)註釋
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
    // 單行註釋
    var item = (Name: "eggplant", Price: 1.99m, perPackage: 3);

    /* 多行註釋(可以寫一行,也可以寫多行) */
    var date = DateTime.Now;

    /*
    多行註釋
    註釋註釋
    註釋
    */
    Console.WriteLine($"On {date}, the price of {item.Name} was {item.Price:C2} per {item.perPackage} items.");

    /*
    * 這樣比較好看
    * 嗯呢,好看
    * 漂亮
    */
    Console.WriteLine();

    Console./*這是有多閒才這麼寫啊*/WriteLine();
}

編譯器會忽略所有的註釋,所以生成的程序集中看不到源代碼中的任何註釋。

總結

一門語言的語法是一套規則,用於管理語言中各有效語句組合在一起的方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章