C# 語言教學:開發實戰指南
C# (C Sharp) 是一種現代、物件導向且型別安全的程式語言,由 Microsoft 開發,旨在 .NET 框架上運行。它結合了 C++ 的強大功能與 Java 的簡潔性,並在過去二十年中不斷發展,成為開發各種應用程式的基石,從桌面應用程式、Web 服務、雲端解決方案到遊戲開發 (Unity) 和行動應用程式,無所不包。
本文將提供一個全面的 C# 語言教學,從基礎語法到進階概念,並著重於實際開發的最佳實踐,幫助讀者掌握 C# 並應用於現實世界的專案。
I. C# 簡介
A. 什麼是 C#?
C# 是一種多範式程式語言,主要支援物件導向程式設計 (OOP)。它由 Anders Hejlsberg 領導的團隊於 2000 年開發,是 .NET 平台的核心語言。C# 的設計目標是成為一種簡單、現代、通用、物件導向的程式語言,並且能夠編寫可靠且高性能的應用程式。
B. C# 的歷史與演變
自推出以來,C# 經歷了多次重大更新,每個版本都引入了新功能,使其更加強大和富有表現力。例如,LINQ (Language Integrated Query) 在 C# 3.0 中引入,簡化了資料查詢;async/await 在 C# 5.0 中引入,徹底改變了非同步程式設計;而 C# 8.0 及更高版本則不斷帶來模式匹配、Nullable 參考型別等創新,提升了開發效率和程式碼品質。
C. 為何學習 C#?(優點、使用案例)
- 多功能性:C# 可用於開發各種應用程式,包括:
- Web 應用程式:使用 ASP.NET Core 框架構建高性能的網站和 API。
- 桌面應用程式:透過 WPF 或 WinForms 開發強大的 Windows 桌面軟體。
- 遊戲開發:Unity 遊戲引擎是全球領先的遊戲開發平台之一,其腳本語言就是 C#。
- 行動應用程式:使用 Xamarin 或 .NET MAUI 進行跨平台行動開發。
- 雲端服務:Azure Functions、Azure App Service 等 Microsoft 雲端服務廣泛支援 C#。
- 微服務:構建可擴展、彈性的微服務架構。
- 強大的生態系統:.NET 平台提供了豐富的函式庫、工具和框架,支援從開發到部署的整個生命週期。
- 活躍的社群:龐大的開發者社群意味著豐富的學習資源、技術支援和範例程式碼。
- 企業級應用:C# 和 .NET 在企業級應用開發中佔據主導地位,提供穩定、安全和可擴展的解決方案。
D. C# 在 .NET 生態系統中
C# 是 .NET 平台的核心語言。.NET 是一個免費的開源開發平台,用於構建各種類型的應用程式。它包含:
* Common Language Runtime (CLR):.NET 的虛擬機器,負責執行 C# 編譯後的程式碼 (Common Intermediate Language, CIL),並提供記憶體管理 (垃圾回收)、安全性、異常處理等服務。
* Base Class Library (BCL):一個龐大的函式庫集合,提供了許多常用功能,如檔案 I/O、網路通訊、資料處理等。
* .NET Core / .NET 5+:現代、跨平台的 .NET 實作,取代了舊有的 .NET Framework,可在 Windows、macOS 和 Linux 上運行。
E. 設定您的開發環境
開始 C# 開發,您需要安裝以下工具:
- 安裝 Visual Studio (Community 版):這是 Microsoft 官方提供的整合開發環境 (IDE),包含了編譯器、偵錯器、程式碼編輯器等所有必要的工具。Community 版對於個人開發者和開源專案是免費的。
- 安裝 .NET SDK:軟體開發套件,包含了 .NET runtime、開發工具和函式庫,是編譯和執行 .NET 應用程式的基礎。通常安裝 Visual Studio 時會自動安裝相關的 SDK。
-
您的第一個 “Hello World!” 程式:
打開 Visual Studio,建立一個新的「主控台應用程式」專案。您會看到類似以下程式碼:“`csharp
using System;namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“Hello, World!”);
}
}
}
``Hello, World!`。這標誌著您成功地踏入了 C# 開發的世界!
點擊「啟動」按鈕 (通常是綠色的播放圖示),程式將編譯並在控制台視窗中輸出
II. C# 語言基礎
A. 基本語法和程式結構
C# 程式由命名空間 (namespace)、類別 (class)、方法 (method) 和陳述式 (statement) 組成。
“`csharp
using System; // 引入 System 命名空間,提供 Console 類別
namespace MyFirstApp // 宣告一個命名空間,用於組織程式碼
{
class Program // 宣告一個類別
{
static void Main(string[] args) // 程式的進入點 (Main 方法)
{
// 這是單行註解
/
* 這是多行註解
/
Console.WriteLine(“歡迎學習 C#!”); // 輸出文字到控制台
}
}
}
“`
B. 資料型別
C# 是一種強型別語言,變數在宣告時必須指定型別。
- 實值型別 (Value Types):直接儲存資料,如
int(整數)、float(單精度浮點數)、double(雙精度浮點數)、bool(布林值)、char(字元)、struct(結構體)。
csharp
int age = 30;
double price = 19.99;
bool isActive = true;
char initial = 'J'; - 參考型別 (Reference Types):儲存資料的記憶體位址,如
string(字串)、class(類別)、interface(介面)、array(陣列)。
csharp
string name = "Gemini";
Program myProgram = new Program(); // 實例化一個類別 - 型別轉換 (Type Conversion):
- 隱式轉換 (Implicit):從較小範圍到較大範圍的轉換,不會丟失資料。
csharp
int myInt = 10;
double myDouble = myInt; // 隱式轉換:int -> double - 顯式轉換 (Explicit) (鑄造
cast):從較大範圍到較小範圍的轉換,可能丟失資料,需要強制轉換。
csharp
double anotherDouble = 9.81;
int anotherInt = (int)anotherDouble; // 顯式轉換:double -> int (結果為 9)
- 隱式轉換 (Implicit):從較小範圍到較大範圍的轉換,不會丟失資料。
C. 變數與常數
- 變數 (Variables):用於儲存資料的具名記憶體位置,其值在程式執行期間可以改變。
csharp
int count = 0;
string message = "Hello"; var關鍵字:C# 3.0 引入,允許編譯器根據初始化表達式自動推斷變數的型別。
csharp
var inferredInt = 100; // 編譯器推斷為 int
var inferredString = "World"; // 編譯器推斷為 string- 常數 (Constants):使用
const關鍵字宣告,其值一旦初始化後就不能改變。
csharp
const double PI = 3.14159;
const string APP_NAME = "My Application";
D. 運算子
C# 支援多種運算子:
- 算術運算子:
+,-,*,/,%(模數),++(遞增),--(遞減) - 關係運算子:
==(等於),!=(不等於),<,>,<=,>= - 邏輯運算子:
&&(邏輯與),||(邏輯或),!(邏輯非) - 賦值運算子:
=,+=,-=,*=,/=,%= - 條件 (三元) 運算子:
condition ? expression1 : expression2;
E. 流程控制語句
- 條件語句:
if-else:
csharp
int x = 10;
if (x > 5)
{
Console.WriteLine("x 大於 5");
}
else if (x == 5)
{
Console.WriteLine("x 等於 5");
}
else
{
Console.WriteLine("x 小於 5");
}switch:
csharp
string day = "Monday";
switch (day)
{
case "Monday":
Console.WriteLine("星期一");
break;
case "Tuesday":
Console.WriteLine("星期二");
break;
default:
Console.WriteLine("其他日子");
break;
}
- 迴圈語句:
for:
csharp
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"for 迴圈次數: {i}");
}while:
csharp
int j = 0;
while (j < 3)
{
Console.WriteLine($"while 迴圈次數: {j}");
j++;
}do-while:至少執行一次。
csharp
int k = 0;
do
{
Console.WriteLine($"do-while 迴圈次數: {k}");
k++;
} while (k < 3);foreach:用於遍歷集合 (如陣列、列表)。
csharp
string[] fruits = { "Apple", "Banana", "Cherry" };
foreach (string fruit in fruits)
{
Console.WriteLine($"水果: {fruit}");
}
- 跳轉語句:
break(終止迴圈/switch)、continue(跳過當前迭代)、return(從方法返回)。
F. 方法 (函數)
方法是執行特定任務的程式碼區塊。
“`csharp
class Calculator
{
// 無回傳值,無參數
public void Greet()
{
Console.WriteLine(“Hello!”);
}
// 有回傳值,有參數
public int Add(int a, int b)
{
return a + b;
}
// 參數修飾符:
// ref: 傳址呼叫,變數必須在呼叫前初始化
// out: 傳出參數,方法內必須賦值
// in: 類似 ref 但不可修改
public void Calculate(int num1, ref int num2, out int result)
{
num2++; // num2 的值在方法外也會改變
result = num1 + num2; // result 必須被賦值
}
// 方法多載 (Method Overloading):方法名稱相同,但參數列表不同
public double Add(double a, double b)
{
return a + b;
}
}
“`
G. 陣列與集合
-
陣列 (Arrays):儲存相同型別的固定大小元素的集合。
“`csharp
int[] numbers = new int[5]; // 宣告一個包含 5 個整數的陣列
numbers[0] = 10;
int[] primes = { 2, 3, 5, 7, 11 }; // 宣告並初始化
Console.WriteLine(primes[2]); // 輸出 5// 多維陣列
int[,] matrix = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };// 不規則陣列 (Jagged Arrays)
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] { 1, 2 };
jaggedArray[1] = new int[] { 3, 4, 5 };
* **集合 (Collections)**:提供更靈活的資料儲存和操作方式。csharp
* `List<T>`:動態大小的同型別元素列表。
Listnames = new List ();
names.Add(“Alice”);
names.Add(“Bob”);
Console.WriteLine(names[0]); // 輸出 Alice
* `Dictionary<TKey, TValue>`:鍵值對集合。csharp
Dictionaryages = new Dictionary ();
ages.Add(“Alice”, 30);
ages.Add(“Bob”, 25);
Console.WriteLine(ages[“Alice”]); // 輸出 30
“`
H. 字串與字串操作
字串是不可變的字元序列。
“`csharp
string firstName = “John”;
string lastName = “Doe”;
string fullName = firstName + ” ” + lastName; // 字串連接
// 字串插值 (String Interpolation):C# 6.0 引入
string greeting = $”Hello, {firstName} {lastName}!”;
Console.WriteLine(greeting); // 輸出 Hello, John Doe!
// 常用字串方法
Console.WriteLine(fullName.Length); // 長度
Console.WriteLine(fullName.Contains(“John”)); // 是否包含
Console.WriteLine(fullName.Replace(“Doe”, “Smith”)); // 替換
Console.WriteLine(fullName.ToUpper()); // 轉大寫
“`
III. C# 中的物件導向程式設計 (OOP)
C# 是一種基於物件導向原則設計的語言,其核心概念包括封裝 (Encapsulation)、繼承 (Inheritance)、多型 (Polymorphism) 和抽象 (Abstraction)。
A. 類別與物件
- 類別 (Class):是一個藍圖或模板,用於創建物件。它定義了物件的屬性 (fields/properties) 和行為 (methods)。
- 物件 (Object):是類別的實例,具有類別定義的屬性和行為。
“`csharp
// 宣告一個 Person 類別
public class Person
{
// 屬性 (Property)
public string Name { get; set; }
public int Age { get; set; }
// 建構函數 (Constructor) - 用於初始化物件
public Person(string name, int age)
{
Name = name;
Age = age;
}
// 方法 (Method)
public void SayHello()
{
Console.WriteLine($"你好,我的名字是 {Name},我今年 {Age} 歲。");
}
}
// 在 Main 方法中創建物件
// Person person1 = new Person(“張三”, 25);
// person1.SayHello(); // 輸出:你好,我的名字是 張三,我今年 25 歲。
“`
B. 封裝 (Encapsulation)
封裝是將資料 (屬性) 和處理資料的方法 (行為) 捆綁在一起,並限制從外部直接存取物件的內部細節。這透過存取修飾符 (Access Modifiers) 和屬性 (Properties) 實現。
- 存取修飾符:
public:公開,任何地方都可存取。private:私有,只能在宣告它的類別內部存取。protected:保護,只能在宣告它的類別及其衍生類別中存取。internal:內部,只能在同一個組件 (Assembly) 內部存取。protected internal:在同一個組件內部或在衍生類別中存取。private protected:在同一個組件內部,且僅在衍生類別中存取。
- 屬性 (Properties):提供彈性機制來讀取、寫入或計算私有欄位的值。
“`csharp
public class BankAccount
{
private decimal _balance; // 私有欄位// 自動實作屬性 (Auto-implemented Property) - C# 會自動創建一個私有後備欄位 public string AccountNumber { get; private set; } // 只能在類別內部設定 // 完整屬性,包含 get 和 set 存取器 public decimal Balance { get { return _balance; } set { if (value >= 0) // 邏輯檢查 { _balance = value; } else { Console.WriteLine("餘額不能為負數。"); } } } public BankAccount(string accountNumber, decimal initialBalance) { AccountNumber = accountNumber; Balance = initialBalance; }}
“`
C. 繼承 (Inheritance)
繼承允許一個類別 (衍生類別/子類別) 從另一個類別 (基底類別/父類別) 繼承屬性和方法。這促進了程式碼的重用和擴展性。
“`csharp
public class Animal // 基底類別
{
public string Name { get; set; }
public Animal(string name)
{
Name = name;
}
public void Eat()
{
Console.WriteLine($"{Name} 正在吃東西。");
}
}
public class Dog : Animal // Dog 類別繼承自 Animal
{
public string Breed { get; set; }
// 衍生類別的建構函數必須呼叫基底類別的建構函數
public Dog(string name, string breed) : base(name)
{
Breed = breed;
}
public void Bark()
{
Console.WriteLine($"{Name} (品種: {Breed}) 正在吠叫。");
}
}
// Dog myDog = new Dog(“Buddy”, “Golden Retriever”);
// myDog.Eat(); // 繼承自 Animal
// myDog.Bark(); // Dog 自己的方法
“`
D. 多型 (Polymorphism)
多型意味著「許多形式」,它允許我們以不同的方式處理相同介面的物件。在 C# 中,多型主要透過方法覆寫 (Method Overriding)、抽象類別和介面實現。
-
方法覆寫 (
virtual,override):基底類別的方法標記為virtual,衍生類別可以透過override關鍵字提供自己的實作。
“`csharp
public class Shape
{
public virtual void Draw() // 虛擬方法,可被覆寫
{
Console.WriteLine(“繪製一個形狀。”);
}
}public class Circle : Shape
{
public override void Draw() // 覆寫基底類別的 Draw 方法
{
Console.WriteLine(“繪製一個圓形。”);
}
}public class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine(“繪製一個矩形。”);
}
}// Shape s1 = new Circle();
// Shape s2 = new Rectangle();
// s1.Draw(); // 輸出:繪製一個圓形。
// s2.Draw(); // 輸出:繪製一個矩形。
2. **方法隱藏 (`new` 關鍵字)**:如果衍生類別的方法與基底類別的方法同名但沒有 `virtual` 關鍵字,可以使用 `new` 關鍵字隱藏基底類別的方法。通常不推薦,因為容易造成混淆。csharp
3. **抽象類別 (Abstract Classes)**:
* 不能直接實例化。
* 可以包含抽象方法 (沒有實作的方法,必須在衍生類別中覆寫) 和具體方法。
* 用於定義一系列相關類別的共同介面和部分實作。
public abstract class Employee // 抽象類別
{
public string Name { get; set; }
public abstract decimal CalculateSalary(); // 抽象方法,沒有實作public void Work() { Console.WriteLine($"{Name} 正在工作。"); }}
public class FullTimeEmployee : Employee
{
public decimal MonthlySalary { get; set; }
public FullTimeEmployee(string name, decimal monthlySalary)
{
Name = name;
MonthlySalary = monthlySalary;
}
public override decimal CalculateSalary() // 必須實作抽象方法
{
return MonthlySalary;
}
}
4. **介面 (Interfaces)**:csharp
* 完全抽象的藍圖,只包含方法簽名、屬性、事件或索引子的宣告,沒有實作。
* 類別可以實作多個介面,實現多重繼承的效果。
* 用於定義類別應遵守的契約。
public interface ILogger
{
void LogInfo(string message);
void LogError(string message);
}public class ConsoleLogger : ILogger
{
public void LogInfo(string message)
{
Console.WriteLine($”[INFO] {message}”);
}public void LogError(string message) { Console.Error.WriteLine($"[ERROR] {message}"); }}
“`
E. 抽象 (Abstraction)
抽象是從複雜事物中提取關鍵資訊,隱藏不重要的細節。透過抽象類別和介面,我們可以定義行為,而不必擔心其實作細節。
- 抽象類別 vs. 介面:
- 抽象類別:可以有實作,可以有建構函數,可以包含欄位。一個類別只能繼承一個抽象類別。適用於「is-a」關係 (例如
Dog is an Animal),當有一部分通用實作時。 - 介面:完全抽象,沒有實作,沒有建構函數,不能包含欄位 (C# 8 以前)。一個類別可以實作多個介面。適用於「can-do」關係 (例如
ConsoleLogger can Log),當需要定義一個行為契約時。
- 抽象類別:可以有實作,可以有建構函數,可以包含欄位。一個類別只能繼承一個抽象類別。適用於「is-a」關係 (例如
F. 建構函數與解構函數
- 建構函數 (Constructors):特殊方法,在建立類別實例時自動呼叫,用於初始化物件的狀態。
- 預設建構函數:如果沒有定義任何建構函數,C# 會自動提供一個無參數的預設建構函數。
- 參數化建構函數:接受參數來初始化屬性。
- 靜態建構函數:在類別的任何靜態成員被存取之前,或者在類別的任何實例被建立之前,靜態建構函數只執行一次。
- 解構函數 (Destructors):用
~符號標記,在物件被垃圾回收器銷毀之前執行。在 C# 中很少使用,因為 .NET 的垃圾回收器會自動處理記憶體管理。
G. 靜態成員 (Static Members)
靜態成員屬於類別本身,而不是類別的任何特定實例。可以直接透過類別名稱存取。
- 靜態欄位:
csharp
public class MySettings
{
public static string AppName = "My C# App"; // 靜態欄位
}
// Console.WriteLine(MySettings.AppName); - 靜態方法:
csharp
public static class Utility
{
public static int Multiply(int a, int b) // 靜態方法
{
return a * b;
}
}
// Console.WriteLine(Utility.Multiply(5, 3)); - 靜態類別:不能被實例化,所有成員都必須是靜態的。
IV. 進階 C# 概念
A. 異常處理 (Exception Handling)
異常處理用於優雅地處理程式執行期間發生的錯誤或異常情況。
try-catch-finally區塊:try:包含可能引發異常的程式碼。catch:捕獲並處理特定型別的異常。finally:無論是否發生異常,都一定會執行的程式碼區塊 (常用於資源清理)。
csharp
try
{
int[] arr = new int[5];
Console.WriteLine(arr[10]); // 會引發 IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine($"陣列索引越界錯誤: {ex.Message}");
}
catch (Exception ex) // 捕獲所有其他異常
{
Console.WriteLine($"發生未知錯誤: {ex.Message}");
}
finally
{
Console.WriteLine("異常處理區塊執行完畢。");
}
throw關鍵字:手動拋出異常。- 自訂異常 (Custom Exceptions):您可以建立自己的異常類別,通常繼承自
Exception類別。
B. 委派 (Delegates) 與事件 (Events)
-
委派 (Delegates):型別安全的函數指標,可以指向具有特定簽名 (回傳型別和參數列表) 的方法。
“`csharp
public delegate void MyDelegate(string message); // 宣告一個委派public class Messenger
{
public void SendMessage(string msg)
{
Console.WriteLine($”傳送訊息: {msg}”);
}
}
// MyDelegate del = new MyDelegate(new Messenger().SendMessage);
// del(“Hello Delegate!”);
* **事件 (Events)**:基於委派的機制,允許物件通知其他物件發生了某事。事件發布者 (publisher) 引發事件,事件訂閱者 (subscriber) 處理事件。csharp
public class Button
{
public event MyDelegate Clicked; // 宣告一個事件public void SimulateClick() { Console.WriteLine("按鈕被點擊了!"); Clicked?.Invoke("按鈕被點擊的訊息"); // 引發事件 }}
// Button btn = new Button();
// Messenger msg = new Messenger();
// btn.Clicked += msg.SendMessage; // 訂閱事件
// btn.SimulateClick();
“`
C. 泛型 (Generics)
泛型允許您設計可以適用於任何資料型別的類別和方法,同時保持型別安全。這可以提高程式碼的重用性並減少重複。
“`csharp
public class GenericList
{
private T[] _items = new T[10];
private int _count = 0;
public void Add(T item)
{
if (_count < _items.Length)
{
_items[_count++] = item;
}
}
public T Get(int index)
{
return _items[index];
}
}
// GenericList
// intList.Add(10);
// int intValue = intList.Get(0);
// GenericList
// stringList.Add(“Test”);
// string stringValue = stringList.Get(0);
``where T : class
* **泛型約束 (Constraints)**:可以限制泛型型別的種類,例如(必須是參考型別),where T : struct(必須是實值型別),where T : new()` (必須有公共無參數建構函數)。
D. LINQ (Language Integrated Query)
LINQ 是一種強大的功能,它將查詢能力直接整合到 C# 語言中,可以用統一的語法查詢不同來源的資料 (如物件集合、資料庫、XML)。
“`csharp
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
List
{
new Student { Name = “Alice”, Age = 20 },
new Student { Name = “Bob”, Age = 22 },
new Student { Name = “Charlie”, Age = 20 }
};
// 查詢語法 (Query Syntax)
var youngStudentsQuery = from s in students
where s.Age < 25
orderby s.Name
select s.Name;
// 方法語法 (Method Syntax)
var youngStudentsMethod = students
.Where(s => s.Age < 25)
.OrderBy(s => s.Name)
.Select(s => s.Name);
foreach (var name in youngStudentsMethod)
{
Console.WriteLine(name); // 輸出 Alice, Bob, Charlie (排序後)
}
``Where
* 常用 LINQ 運算子:(篩選),Select(投影),OrderBy(排序),GroupBy(分組),Join` (連接)。
E. 非同步程式設計 (async 和 await)
async 和 await 關鍵字徹底改變了 C# 中的非同步程式設計,使其變得簡單易懂。它們允許您編寫非阻塞的程式碼,提高應用程式的響應能力,特別適用於 I/O 密集型操作 (如網路請求、檔案讀寫)。
“`csharp
public async Task DownloadPageAsync(string url)
{
using (HttpClient client = new HttpClient())
{
Console.WriteLine($”開始下載 {url}…”);
string content = await client.GetStringAsync(url); // 等待非同步操作完成
Console.WriteLine($”下載完成,內容長度: {content.Length}”);
}
}
// 在 Main 方法中呼叫
// await DownloadPageAsync(“https://www.google.com”);
``Task` 平行庫 (Task Parallel Library, TPL):提供了用於建立和管理並行任務的型別。
*
F. 檔案 I/O 和資料流
C# 提供了豐富的 API 來處理檔案和目錄,以及讀取和寫入資料流。
“`csharp
string filePath = “mydata.txt”;
// 寫入文字檔
using (StreamWriter writer = new StreamWriter(filePath))
{
writer.WriteLine(“這是第一行。”);
writer.WriteLine(“這是第二行。”);
}
Console.WriteLine($”檔案 ‘{filePath}’ 已寫入。”);
// 讀取文字檔
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine($”讀取到: {line}”);
}
}
Console.WriteLine($”檔案 ‘{filePath}’ 已讀取。”);
// 目錄操作
// Directory.CreateDirectory(“MyFolder”);
// File.Delete(filePath);
“`
G. 屬性 (Attributes)
屬性是一種強大的元資料,可以附加到程式碼元素 (如類別、方法、屬性) 上,在執行時提供額外的資訊。
“`csharp
[Obsolete(“此方法已過時,請改用 NewMethod。”, false)] // Obsolete 屬性
public void OldMethod()
{
Console.WriteLine(“這是舊方法。”);
}
public void NewMethod()
{
Console.WriteLine(“這是新方法。”);
}
“`
H. 反射 (Reflection)
反射允許程式在執行時檢查自身的元資料 (型別資訊、成員資訊) 並動態呼叫成員。
csharp
Type type = typeof(string);
Console.WriteLine($"型別名稱: {type.Name}");
foreach (var method in type.GetMethods())
{
// Console.WriteLine(method.Name); // 輸出 string 類別的所有方法
}
V. C# 實戰開發
A. .NET 平台概覽 (再探討)
現代 .NET (自 .NET 5 起) 是一個統一的平台,取代了 .NET Framework 和 .NET Core,提供了一個單一的基礎框架來構建所有型別的應用程式。它支援跨平台開發,並具有卓越的性能。
B. 建立主控台應用程式
主控台應用程式是 C# 開發的入門,適用於工具、批次處理、學習演算法等。
“`csharp
// 範例:計算兩個數字的和
Console.WriteLine(“請輸入第一個數字:”);
string input1 = Console.ReadLine();
int num1 = int.Parse(input1); // 將字串轉換為整數
Console.WriteLine(“請輸入第二個數字:”);
string input2 = Console.ReadLine();
int num2 = Convert.ToInt32(input2); // 另一種轉換方式
int sum = num1 + num2;
Console.WriteLine($”兩數之和為: {sum}”);
“`
C. ASP.NET Core Web 開發入門
ASP.NET Core 是 Microsoft 用於建構現代、雲端就緒、跨平台 Web 應用程式的開源框架。
- MVC 模式 (Model-View-Controller):一種設計模式,將應用程式分為三個主要組件,以實現職責分離。
- Model:處理應用程式的資料和業務邏輯。
- View:負責呈現使用者介面。
- Controller:處理使用者輸入,與 Model 互動,並選擇要呈現的 View。
- Razor Pages:一種更簡單、頁面為中心的模型,適用於較小的 Web 應用程式或需要快速開發的場景。
- 建構 Web API (RESTful 服務):ASP.NET Core 是建構高效能 RESTful API 的理想選擇,用於為前端應用程式 (如 React, Angular) 提供資料。
D. 桌面應用程式開發 (簡要介紹)
- WPF (Windows Presentation Foundation):基於 XAML 語言的現代 UI 框架,提供豐富的圖形功能和彈性的佈局系統,適用於開發視覺豐富的 Windows 桌面應用程式。
- WinForms (Windows Forms):較舊但仍然廣泛使用的框架,基於拖放控制項,開發速度快,適用於標準業務應用程式。
E. 資料庫連接
- ADO.NET:.NET 框架中用於連接資料庫的基礎技術,提供低層次的資料存取功能。
- Entity Framework Core (ORM):一個流行的物件關係對應 (ORM) 框架,它允許開發人員使用 C# 物件而不是直接使用 SQL 語句來處理資料庫。
- Code-First 方法:您定義 C# 模型類別,Entity Framework Core 會根據這些類別自動生成資料庫架構。
-
執行 CRUD 操作:
“`csharp
// 假設您有一個 DbContext 和一個實體 Student
// using (var context = new MyDbContext())
// {
// // Create
// var newStudent = new Student { Name = “David”, Age = 21 };
// context.Students.Add(newStudent);
// context.SaveChanges();// // Read
// var student = context.Students.FirstOrDefault(s => s.Name == “David”);
// Console.WriteLine($”找到學生: {student?.Name}”);// // Update
// if (student != null)
// {
// student.Age = 22;
// context.SaveChanges();
// }// // Delete
// // context.Students.Remove(student);
// // context.SaveChanges();
// }
“`
F. 單元測試 (Unit Testing)
單元測試是軟體開發的重要環節,用於驗證程式碼的最小可測試單元 (通常是方法) 是否按預期工作。
- 單元測試框架:常用的有 NUnit 和 xUnit。
-
編寫測試案例:
“`csharp
// 假設有一個 Calculator 類別
public class Calculator
{
public int Add(int a, int b) => a + b;
}// 使用 xUnit 的測試案例
// public class CalculatorTests
// {
// [Fact] // 標記為一個測試方法
// public void Add_TwoNumbers_ReturnsCorrectSum()
// {
// // Arrange (準備)
// Calculator calculator = new Calculator();
// int num1 = 5;
// int num2 = 3;
// int expectedSum = 8;// // Act (執行)
// int actualSum = calculator.Add(num1, num2);// // Assert (斷言)
// Assert.Equal(expectedSum, actualSum);
// }
// }
“`
G. 依賴注入 (Dependency Injection, DI)
依賴注入是一種設計模式,它實現了控制反轉 (Inversion of Control, IoC),使組件之間的依賴關係解耦。在 .NET Core 中,DI 是內建且廣泛使用的。
- 為何使用 DI? 提高模組化、可測試性和可維護性。
- 基本實作:透過建構函數注入或屬性注入來提供依賴。
H. 日誌記錄 (Logging)
日誌記錄是應用程式監控、偵錯和審計的關鍵。
- .NET 內建的日誌系統。
- 第三方函式庫:如 Serilog、NLog 提供更強大、靈活的日誌功能。
I. 版本控制 (Git 基礎)
對於任何規模的專案,使用 Git 進行版本控制都是必不可少的。它允許團隊協同工作,追蹤程式碼變更,並在需要時回溯。
VI. 最佳實踐與提示
A. 編碼標準與風格指南
- C# 命名約定:
- 類別、方法、屬性、命名空間:PascalCase (例如
MyClass,MyMethod) - 局部變數、方法參數:camelCase (例如
myVariable,myParameter) - 常數:PascalCase 或全部大寫 (例如
MaxCount,MAX_VALUE) - 私有欄位:
_camelCase(例如_myField)
- 類別、方法、屬性、命名空間:PascalCase (例如
- 程式碼格式:保持一致的縮排、空格和換行,提高可讀性。Visual Studio 提供了強大的格式化工具。
- 註解:僅在必要時添加註解,解釋複雜邏輯或非顯而易見的設計決策,而不是解釋顯而易見的程式碼。
B. 程式碼優化與性能考量
- 避免不必要的物件建立:減少垃圾回收的壓力。
- 使用
StringBuilder處理大量字串連接:string是不可變的,大量連接會產生許多中間物件。 - 選擇正確的集合型別:根據使用場景選擇
List<T>,Dictionary<TKey, TValue>,HashSet<T>等。 - 利用非同步程式設計:避免阻塞 I/O 操作。
- 效能分析工具:使用 Visual Studio 的效能分析工具來識別瓶頸。
C. 安全性考量
- 輸入驗證:始終驗證所有來自使用者的輸入,防止 SQL 注入、跨站指令碼 (XSS) 等攻擊。
- 身份驗證與授權:正確實作使用者身份驗證 (你是誰?) 和授權 (你能做什麼?)。
- 使用參數化查詢:永遠不要直接將使用者輸入拼接到 SQL 語句中。
- 敏感資訊保護:不要將密碼、API 金鑰等敏感資訊硬編碼到程式碼中。
D. Visual Studio 偵錯技巧
- 斷點 (Breakpoints):在程式碼中設定斷點,讓程式在指定行暫停。
- 逐步執行:
F10(逐步執行)、F11(逐步進入)、Shift+F11(逐步跳出)。 - 監看視窗 (Watch Window):監控變數的值。
- 即時視窗 (Immediate Window):在偵錯時執行程式碼或評估表達式。
- 呼叫堆疊 (Call Stack):查看方法呼叫的順序。
E. 持續學習資源
- Microsoft Learn:官方文件和教學課程。
- Stack Overflow:程式設計問答社群。
- GitHub:開源專案和範例程式碼。
- 技術書籍與部落格:深入學習特定領域知識。
- 技術社群與會議:與其他開發者交流。
VII. 結論
C# 是一種功能強大、用途廣泛且不斷發展的語言,擁有一個成熟且豐富的生態系統。透過掌握其基礎語法、物件導向原則、進階功能以及實戰開發技巧,您將能夠構建出高效能、可維護且安全的各種應用程式。
從 “Hello World!” 到複雜的企業級解決方案,C# 和 .NET 平台提供了您所需的一切工具和資源。持續學習、實踐和探索,將是您成為一名優秀 C# 開發者的關鍵。現在,就開始您的 C# 開發之旅吧!