C# 語法大全:從入門到精通
《C#编程语言全面指南》摘要:本文系统介绍了C#语言的核心知识体系,从基础语法到高级特性,涵盖数据类型、控制流程、面向对象编程、泛型、LINQ查询、异步编程等关键内容。重点内容包括:1. C#发展历程及版本特性演变;2. 面向对象三大特性(封装、继承、多态)的实现;3. 现代特性如委托、Lambda表达式、扩展方法;4. 集合框架与泛型编程;5. LINQ数据查询技术;6. async/await
C# 語法大全:從入門到精通
目錄
-
C# 語言簡介
-
基礎語法與數據類型
-
控制流程語句
-
面向對象編程
-
高級特性與委託
-
泛型與集合
-
LINQ 查詢
-
異步編程
-
屬性與反射
-
C# 新特性
C# 語言簡介
什麼是 C#?
C#(發音為 "C Sharp")是由 Microsoft 開發的現代、面向對象、類型安全的編程語言,運行在 .NET 框架上。它結合了 C++ 的強大功能和 Visual Basic 的簡單易用性,成為 .NET 平台的主要開發語言。
C# 的發展歷史
-
2000年:C# 1.0 發布,隨 .NET Framework 1.0
-
2005年:C# 2.0 引入泛型
-
2007年:C# 3.0 引入 LINQ
-
2010年:C# 4.0 引入動態類型
-
2012年:C# 5.0 引入 async/await
-
2015年:C# 6.0 引入許多語法糖
-
2017年:C# 7.0 引入模式匹配等
-
2019年:C# 8.0 引入可空引用類型等
-
2020年:C# 9.0 引入記錄類型等
-
2021年:C# 10.0 引入全局 using 等
-
2022年:C# 11.0 引入原始字符串字面量等
-
2023年:C# 12.0 引入主構造函數等
第一個 C# 程序
csharp
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
// 等待用戶輸入
Console.ReadLine();
}
}
}
基礎語法與數據類型
變量與常量
csharp
using System;
class VariablesDemo
{
public static void Demo()
{
// 變量聲明與初始化
int age = 25;
string name = "John Doe";
double salary = 50000.50;
bool isEmployed = true;
char grade = 'A';
// 常量聲明
const double PI = 3.14159;
const int DAYS_IN_WEEK = 7;
// 隱式類型變量 (類型推斷)
var message = "Hello World"; // 編譯器推斷為 string
var count = 10; // 編譯器推斷為 int
var price = 9.99m; // 編譯器推斷為 decimal
// 顯示類型信息
Console.WriteLine($"Type of message: {message.GetType()}");
Console.WriteLine($"Type of count: {count.GetType()}");
Console.WriteLine($"Type of price: {price.GetType()}");
// 空值處理
string? nullableString = null; // 可空引用類型 (C# 8.0+)
int? nullableInt = null; // 可空值類型
// 空條件運算符
int length = nullableString?.Length ?? 0;
Console.WriteLine($"String length: {length}");
}
}
基本數據類型
值類型 (Value Types)
csharp
class ValueTypesDemo
{
public static void Demo()
{
// 整數類型
byte byteValue = 255; // 0 到 255
sbyte sbyteValue = -128; // -128 到 127
short shortValue = -32768; // -32,768 到 32,767
ushort ushortValue = 65535; // 0 到 65,535
int intValue = -2147483648; // -2,147,483,648 到 2,147,483,647
uint uintValue = 4294967295; // 0 到 4,294,967,295
long longValue = -9223372036854775808; // -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
ulong ulongValue = 18446744073709551615; // 0 到 18,446,744,073,709,551,615
// 浮點數類型
float floatValue = 3.14159f; // 7 位精度
double doubleValue = 3.14159265358979; // 15-16 位精度
decimal decimalValue = 3.14159265358979323846m; // 28-29 位精度
// 其他值類型
char charValue = 'A';
bool boolValue = true;
// 枚舉類型
DayOfWeek today = DayOfWeek.Monday;
// 結構體
Point point = new Point(10, 20);
Console.WriteLine($"Integer range: {int.MinValue} to {int.MaxValue}");
Console.WriteLine($"Double range: {double.MinValue} to {double.MaxValue}");
}
// 結構體定義
struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
}
// 枚舉定義
enum DayOfWeek
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
}
引用類型 (Reference Types)
csharp
class ReferenceTypesDemo
{
public static void Demo()
{
// 字符串
string str1 = "Hello";
string str2 = "World";
string str3 = str1 + " " + str2;
// 字符串插值 (C# 6.0+)
string interpolated = $"{str1} {str2} from C#";
// 原始字符串字面量 (C# 11.0+)
string rawString = """
This is a raw string literal.
It can span multiple lines
and doesn't need escape sequences for quotes: "Hello"
""";
// 對象
object obj = "This is an object";
// 動態類型
dynamic dynamicVar = 10;
dynamicVar = "Now I'm a string";
dynamicVar = new { Name = "John", Age = 30 };
// 數組
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
string[] names = { "Alice", "Bob", "Charlie" };
// 多維數組
int[,] matrix = new int[3, 3]
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
// 交錯數組 (數組的數組)
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] { 1, 2, 3 };
jaggedArray[1] = new int[] { 4, 5 };
jaggedArray[2] = new int[] { 6, 7, 8, 9 };
}
}
運算符
csharp
class OperatorsDemo
{
public static void Demo()
{
int a = 10, b = 3;
// 算術運算符
int sum = a + b; // 13
int difference = a - b; // 7
int product = a * b; // 30
int quotient = a / b; // 3 (整數除法)
int remainder = a % b; // 1
int increment = ++a; // 先增加再賦值
int decrement = --a; // 先減少再賦值
// 賦值運算符
a += 5; // a = a + 5
a -= 3; // a = a - 3
a *= 2; // a = a * 2
a /= 4; // a = a / 4
a %= 3; // a = a % 3
// 比較運算符
bool isEqual = (a == b); // false
bool notEqual = (a != b); // true
bool greaterThan = (a > b); // true
bool lessThan = (a < b); // false
bool greaterOrEqual = (a >= b); // true
bool lessOrEqual = (a <= b); // false
// 邏輯運算符
bool x = true, y = false;
bool andResult = x && y; // false
bool orResult = x || y; // true
bool notResult = !x; // false
// 位運算符
int bitwiseAnd = a & b;
int bitwiseOr = a | b;
int bitwiseXor = a ^ b;
int bitwiseNot = ~a;
int leftShift = a << 2;
int rightShift = a >> 2;
// 三元條件運算符
string result = (a > b) ? "a is greater" : "b is greater";
// 空合並運算符 (??)
string name1 = null;
string displayName = name1 ?? "Default Name";
// 空合並賦值運算符 (??=) (C# 8.0+)
string name2 = null;
name2 ??= "Default Value";
// 空條件運算符 (?.)
Person person = null;
int? age = person?.Age; // 如果 person 為 null,則 age 為 null
// 索引運算符 (用於數組和集合)
int[] numbers = { 1, 2, 3, 4, 5 };
int first = numbers[0];
numbers[2] = 10;
// 範圍運算符 (C# 8.0+)
var slice = numbers[1..4]; // 獲取索引 1 到 3 的元素
var startSlice = numbers[..3]; // 從開始到索引 2
var endSlice = numbers[2..]; // 從索引 2 到結束
var allButLast = numbers[..^1]; // 除最後一個外的所有元素
// ^ 運算符 (C# 8.0+)
int last = numbers[^1]; // 最後一個元素
int secondLast = numbers[^2]; // 倒數第二個元素
}
}
class Person
{
public int Age { get; set; }
}
類型轉換
csharp
class TypeConversionDemo
{
public static void Demo()
{
// 隱式轉換 (小類型到大類型)
int intValue = 100;
long longValue = intValue; // 隱式轉換
// 顯式轉換 (大類型到小類型)
double doubleValue = 9.78;
int intFromDouble = (int)doubleValue; // 顯式轉換,丟失小數部分
// Convert 類
string strNumber = "123";
int convertedNumber = Convert.ToInt32(strNumber);
// Parse 方法
int parsedNumber = int.Parse("456");
// TryParse 方法 (推薦)
string input = "789";
if (int.TryParse(input, out int result))
{
Console.WriteLine($"Parsed successfully: {result}");
}
else
{
Console.WriteLine("Parsing failed");
}
// 使用 System.Convert
decimal decimalValue = Convert.ToDecimal("123.45");
bool boolValue = Convert.ToBoolean("true");
// 拆箱和裝箱
int valueType = 42;
object boxed = valueType; // 裝箱
int unboxed = (int)boxed; // 拆箱
// as 運算符 (安全轉換)
object obj = "Hello";
string str = obj as string; // 如果轉換失敗,返回 null
// is 運算符 (類型檢查)
if (obj is string)
{
Console.WriteLine("obj is a string");
}
// 模式匹配中的 is (C# 7.0+)
if (obj is string s)
{
Console.WriteLine($"obj is a string with value: {s}");
}
// 自定義轉換運算符
Temperature temp = 25; // 隱式轉換
double celsius = (double)temp; // 顯式轉換
}
}
// 自定義類型轉換示例
class Temperature
{
private double Celsius { get; }
public Temperature(double celsius)
{
Celsius = celsius;
}
// 隱式轉換運算符
public static implicit operator Temperature(double celsius)
{
return new Temperature(celsius);
}
// 顯式轉換運算符
public static explicit operator double(Temperature temp)
{
return temp.Celsius;
}
}
控制流程語句
條件語句
csharp
class ControlFlowDemo
{
public static void Demo()
{
int score = 85;
// if-else 語句
if (score >= 90)
{
Console.WriteLine("Grade: A");
}
else if (score >= 80)
{
Console.WriteLine("Grade: B");
}
else if (score >= 70)
{
Console.WriteLine("Grade: C");
}
else
{
Console.WriteLine("Grade: F");
}
// 三元運算符
string status = (score >= 60) ? "Pass" : "Fail";
// switch 語句 (傳統)
char grade = 'B';
switch (grade)
{
case 'A':
Console.WriteLine("Excellent");
break;
case 'B':
case 'C':
Console.WriteLine("Good");
break;
case 'D':
Console.WriteLine("Pass");
break;
case 'F':
Console.WriteLine("Fail");
break;
default:
Console.WriteLine("Invalid grade");
break;
}
// switch 表達式 (C# 8.0+)
string gradeDescription = grade switch
{
'A' => "Excellent",
'B' or 'C' => "Good",
'D' => "Pass",
'F' => "Fail",
_ => "Invalid grade"
};
// 模式匹配的 switch (C# 7.0+)
object obj = 42;
switch (obj)
{
case int i when i > 0:
Console.WriteLine($"Positive integer: {i}");
break;
case int i when i < 0:
Console.WriteLine($"Negative integer: {i}");
break;
case string s:
Console.WriteLine($"String: {s}");
break;
case null:
Console.WriteLine("Null object");
break;
default:
Console.WriteLine("Unknown type");
break;
}
}
}
循環語句
csharp
class LoopsDemo
{
public static void Demo()
{
// for 循環
Console.WriteLine("for loop:");
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"i = {i}");
}
// 嵌套 for 循環
Console.WriteLine("\nNested for loop (multiplication table):");
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
Console.Write($"{i * j}\t");
}
Console.WriteLine();
}
// while 循環
Console.WriteLine("\nwhile loop:");
int counter = 0;
while (counter < 3)
{
Console.WriteLine($"Counter: {counter}");
counter++;
}
// do-while 循環 (至少執行一次)
Console.WriteLine("\ndo-while loop:");
int number;
do
{
Console.Write("Enter a positive number: ");
// 實際應用中這裡會有輸入邏輯
number = 1; // 示例值
} while (number <= 0);
// foreach 循環
Console.WriteLine("\nforeach loop:");
string[] fruits = { "Apple", "Banana", "Cherry", "Date" };
foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}
// 帶索引的 foreach (C# 8.0+)
Console.WriteLine("\nforeach with index:");
foreach (var (index, fruit) in fruits.Select((value, i) => (i, value)))
{
Console.WriteLine($"Index {index}: {fruit}");
}
// 循環控制語句
Console.WriteLine("\nLoop control statements:");
// break - 退出循環
for (int i = 0; i < 10; i++)
{
if (i == 5)
break;
Console.WriteLine($"i = {i}");
}
// continue - 跳過本次迭代
Console.WriteLine("\nContinue example:");
for (int i = 0; i < 5; i++)
{
if (i == 2)
continue;
Console.WriteLine($"i = {i}");
}
// goto - 跳轉到標籤 (不推薦使用)
Console.WriteLine("\nGoto example:");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (i == 1 && j == 1)
goto endLoop;
Console.WriteLine($"i={i}, j={j}");
}
}
endLoop:
Console.WriteLine("Loop ended with goto");
// 無限循環
/*
while (true)
{
// 需要 break 語句來退出
break;
}
*/
// 使用 Range 和 Indices 的循環 (C# 8.0+)
Console.WriteLine("\nUsing ranges:");
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foreach (var num in numbers[2..7])
{
Console.Write($"{num} ");
}
Console.WriteLine();
// 反向循環
Console.WriteLine("\nReverse loop:");
for (int i = numbers.Length - 1; i >= 0; i--)
{
Console.Write($"{numbers[i]} ");
}
Console.WriteLine();
// 使用 LINQ 的循環
Console.WriteLine("\nUsing LINQ:");
var evenNumbers = numbers.Where(n => n % 2 == 0);
foreach (var num in evenNumbers)
{
Console.Write($"{num} ");
}
Console.WriteLine();
}
}
面向對象編程
類和對象
csharp
// 基本類定義
public class Person
{
// 字段 (Fields)
private string _name;
private int _age;
// 靜態字段
private static int _totalPeople = 0;
// 常量
public const string Species = "Homo sapiens";
// 只讀字段
private readonly DateTime _createdDate;
// 構造函數
public Person()
{
_name = "Unknown";
_age = 0;
_createdDate = DateTime.Now;
_totalPeople++;
}
// 參數化構造函數
public Person(string name, int age)
{
_name = name;
_age = age;
_createdDate = DateTime.Now;
_totalPeople++;
}
// 主構造函數 (C# 12.0+)
// public class Person(string name, int age) { ... }
// 屬性 (Properties)
public string Name
{
get { return _name; }
set
{
if (!string.IsNullOrWhiteSpace(value))
_name = value;
}
}
public int Age
{
get => _age; // 表達式體成員 (C# 6.0+)
set => _age = value >= 0 ? value : 0;
}
// 自動屬性
public string Address { get; set; } = "Unknown"; // 自動初始值 (C# 6.0+)
// 只讀自動屬性
public DateTime BirthDate { get; }
// 計算屬性
public bool IsAdult => Age >= 18;
// 靜態屬性
public static int TotalPeople => _totalPeople;
// 方法
public void Introduce()
{
Console.WriteLine($"Hello, my name is {Name} and I'm {Age} years old.");
}
// 方法重載
public void Introduce(string greeting)
{
Console.WriteLine($"{greeting}, I'm {Name}");
}
// 靜態方法
public static void DisplaySpecies()
{
Console.WriteLine($"Species: {Species}");
}
// 虛方法 (可被子類重寫)
public virtual void DisplayInfo()
{
Console.WriteLine($"Person: {Name}, {Age} years old");
}
// 析構函數
~Person()
{
_totalPeople--;
Console.WriteLine($"Person {_name} is being destroyed");
}
}
// 使用示例
class ClassDemo
{
public static void Demo()
{
// 創建對象
Person person1 = new Person();
person1.Name = "Alice";
person1.Age = 25;
Person person2 = new Person("Bob", 30);
// 訪問屬性和方法
person1.Introduce();
Console.WriteLine($"Is adult: {person1.IsAdult}");
// 訪問靜態成員
Console.WriteLine($"Total people created: {Person.TotalPeople}");
Person.DisplaySpecies();
// 對象初始化器 (C# 3.0+)
Person person3 = new Person
{
Name = "Charlie",
Age = 35,
Address = "123 Main St"
};
// 使用 with 表達式創建副本 (C# 9.0+ 需要記錄類型)
// var person4 = person3 with { Age = 36 };
}
}
繼承和多態
csharp
// 基類
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public Animal(string name, int age)
{
Name = name;
Age = age;
}
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound");
}
public void Eat()
{
Console.WriteLine($"{Name} is eating");
}
}
// 派生類
public class Dog : Animal
{
public string Breed { get; set; }
// 使用 base 調用基類構造函數
public Dog(string name, int age, string breed)
: base(name, age)
{
Breed = breed;
}
// 重寫虛方法
public override void MakeSound()
{
Console.WriteLine($"{Name} says: Woof! Woof!");
}
// 新方法
public void WagTail()
{
Console.WriteLine($"{Name} is wagging its tail");
}
// 隱藏基類方法 (使用 new 關鍵字)
public new void Eat()
{
Console.WriteLine($"{Name} the dog is eating dog food");
}
}
// 另一個派生類
public class Cat : Animal
{
public bool IsIndoor { get; set; }
public Cat(string name, int age, bool isIndoor)
: base(name, age)
{
IsIndoor = isIndoor;
}
public override void MakeSound()
{
Console.WriteLine($"{Name} says: Meow!");
}
public void Purr()
{
Console.WriteLine($"{Name} is purring");
}
}
// 密封類 (不能被繼承)
public sealed class Lion : Animal
{
public Lion(string name, int age) : base(name, age) { }
public override void MakeSound()
{
Console.WriteLine("Roar!");
}
}
// 抽象類 (不能實例化)
public abstract class Shape
{
public abstract double Area { get; }
public abstract double Perimeter { get; }
// 抽象方法 (必須在派生類中實現)
public abstract void Draw();
// 具體方法
public void DisplayInfo()
{
Console.WriteLine($"Area: {Area}, Perimeter: {Perimeter}");
}
// 虛方法
public virtual void Scale(double factor)
{
Console.WriteLine($"Scaling by factor {factor}");
}
}
// 實現抽象類
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public override double Area => Math.PI * Radius * Radius;
public override double Perimeter => 2 * Math.PI * Radius;
public override void Draw()
{
Console.WriteLine($"Drawing a circle with radius {Radius}");
}
public override void Scale(double factor)
{
Radius *= factor;
Console.WriteLine($"Circle scaled to radius {Radius}");
}
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public override double Area => Width * Height;
public override double Perimeter => 2 * (Width + Height);
public override void Draw()
{
Console.WriteLine($"Drawing a rectangle {Width}x{Height}");
}
}
// 接口
public interface IMovable
{
void Move();
void Stop();
// 默認接口方法 (C# 8.0+)
void Turn()
{
Console.WriteLine("Turning...");
}
// 靜態方法 (C# 8.0+)
static string GetTypeName() => "IMovable";
}
public interface IFlyable
{
void Fly();
int MaxAltitude { get; }
}
// 實現多個接口
public class Bird : Animal, IMovable, IFlyable
{
public int MaxAltitude { get; } = 1000;
public Bird(string name, int age) : base(name, age) { }
public override void MakeSound()
{
Console.WriteLine("Chirp! Chirp!");
}
public void Move()
{
Console.WriteLine($"{Name} is flying");
}
public void Stop()
{
Console.WriteLine($"{Name} has landed");
}
public void Fly()
{
Console.WriteLine($"{Name} is flying at altitude {MaxAltitude}m");
}
}
// 多態演示
class InheritanceDemo
{
public static void Demo()
{
// 繼承示例
Dog dog = new Dog("Buddy", 3, "Golden Retriever");
dog.MakeSound();
dog.Eat();
dog.WagTail();
// 多態示例
Animal myAnimal = new Dog("Max", 2, "Beagle");
myAnimal.MakeSound(); // 調用 Dog 的 MakeSound
myAnimal.Eat(); // 調用 Animal 的 Eat
// 使用基類引用
Animal[] animals = new Animal[3];
animals[0] = new Dog("Rex", 4, "German Shepherd");
animals[1] = new Cat("Whiskers", 2, true);
animals[2] = new Bird("Tweety", 1);
foreach (Animal animal in animals)
{
animal.MakeSound(); // 多態調用
// 類型檢查和轉換
if (animal is Dog d)
{
d.WagTail();
}
if (animal is Cat cat)
{
cat.Purr();
}
}
// 抽象類示例
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(4, 6);
circle.Draw();
circle.DisplayInfo();
circle.Scale(2);
rectangle.Draw();
rectangle.DisplayInfo();
// 接口示例
IMovable[] movables = new IMovable[2];
movables[0] = new Bird("Sparrow", 1);
movables[1] = new Car();
foreach (var movable in movables)
{
movable.Move();
movable.Turn(); // 調用默認接口方法
movable.Stop();
}
// 訪問靜態接口方法
Console.WriteLine($"Interface type: {IMovable.GetTypeName()}");
}
}
public class Car : IMovable
{
public void Move()
{
Console.WriteLine("Car is moving");
}
public void Stop()
{
Console.WriteLine("Car has stopped");
}
}
封裝和訪問修飾符
csharp
// 訪問修飾符演示
class AccessModifiersDemo
{
// public - 無限制訪問
public int PublicField = 1;
// private - 只能在當前類中訪問
private int _privateField = 2;
// protected - 當前類和派生類中訪問
protected int ProtectedField = 3;
// internal - 同一程序集內訪問
internal int InternalField = 4;
// protected internal - 同一程序集或派生類中訪問
protected internal int ProtectedInternalField = 5;
// private protected - 同一程序集中的派生類訪問 (C# 7.2+)
private protected int PrivateProtectedField = 6;
public void TestAccess()
{
// 所有字段都可以在類內部訪問
Console.WriteLine($"Private field: {_privateField}");
}
}
// 派生類
class DerivedClass : AccessModifiersDemo
{
public void TestProtectedAccess()
{
// 可以訪問 protected, protected internal, private protected 字段
Console.WriteLine($"Protected field: {ProtectedField}");
Console.WriteLine($"Protected internal field: {ProtectedInternalField}");
Console.WriteLine($"Private protected field: {PrivateProtectedField}");
// 不能訪問 private 字段
// Console.WriteLine(_privateField); // 編譯錯誤
}
}
// 另一個程序集中的類 (假設)
/*
class ExternalClass
{
public void Test()
{
AccessModifiersDemo demo = new AccessModifiersDemo();
// 只能訪問 public 和 internal 字段
Console.WriteLine(demo.PublicField);
Console.WriteLine(demo.InternalField);
// 不能訪問 protected, private, protected internal
// Console.WriteLine(demo.ProtectedField); // 編譯錯誤
}
}
*/
// 封裝示例
public class BankAccount
{
// 私有字段 - 封裝數據
private decimal _balance;
private string _accountNumber;
private string _ownerName;
private List<Transaction> _transactions;
// 公共屬性 - 提供受控訪問
public decimal Balance
{
get => _balance;
private set => _balance = value; // 只能在類內部設置
}
public string AccountNumber
{
get => _accountNumber;
private set => _accountNumber = value;
}
public string OwnerName
{
get => _ownerName;
set
{
if (!string.IsNullOrWhiteSpace(value))
_ownerName = value;
}
}
// 只讀屬性
public IReadOnlyList<Transaction> Transactions => _transactions.AsReadOnly();
// 構造函數
public BankAccount(string accountNumber, string ownerName, decimal initialBalance = 0)
{
AccountNumber = accountNumber;
OwnerName = ownerName;
_balance = initialBalance;
_transactions = new List<Transaction>();
if (initialBalance > 0)
{
_transactions.Add(new Transaction("Initial deposit", initialBalance));
}
}
// 公共方法 - 提供功能
public void Deposit(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("Deposit amount must be positive");
_balance += amount;
_transactions.Add(new Transaction("Deposit", amount));
Console.WriteLine($"Deposited {amount:C}. New balance: {_balance:C}");
}
public bool Withdraw(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("Withdrawal amount must be positive");
if (amount > _balance)
{
Console.WriteLine("Insufficient funds");
return false;
}
_balance -= amount;
_transactions.Add(new Transaction("Withdrawal", -amount));
Console.WriteLine($"Withdrew {amount:C}. New balance: {_balance:C}");
return true;
}
public void Transfer(BankAccount recipient, decimal amount)
{
if (Withdraw(amount))
{
recipient.Deposit(amount);
_transactions.Add(new Transaction($"Transfer to {recipient.AccountNumber}", -amount));
}
}
public void PrintStatement()
{
Console.WriteLine($"Account Statement for {AccountNumber}");
Console.WriteLine($"Owner: {OwnerName}");
Console.WriteLine($"Balance: {_balance:C}");
Console.WriteLine("\nTransactions:");
foreach (var transaction in _transactions)
{
Console.WriteLine($"{transaction.Date:yyyy-MM-dd}: {transaction.Description} {transaction.Amount:C}");
}
}
// 私有方法 - 內部實現細節
private void ValidateAmount(decimal amount)
{
if (amount < 0)
throw new ArgumentException("Amount cannot be negative");
}
}
public class Transaction
{
public DateTime Date { get; }
public string Description { get; }
public decimal Amount { get; }
public Transaction(string description, decimal amount)
{
Date = DateTime.Now;
Description = description;
Amount = amount;
}
}
結構體與枚舉
csharp
// 枚舉定義
public enum DayOfWeek
{
Sunday, // 0
Monday, // 1
Tuesday, // 2
Wednesday, // 3
Thursday, // 4
Friday, // 5
Saturday // 6
}
// 指定值的枚舉
public enum HttpStatusCode
{
OK = 200,
Created = 201,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404,
InternalServerError = 500
}
// 標誌枚舉 (用於位操作)
[Flags]
public enum FilePermissions
{
None = 0, // 0
Read = 1, // 1 << 0
Write = 2, // 1 << 1
Execute = 4, // 1 << 2
ReadWrite = Read | Write, // 3
All = Read | Write | Execute // 7
}
// 結構體 - 值類型
public struct Point
{
// 字段
public int X;
public int Y;
// 屬性
public double Magnitude => Math.Sqrt(X * X + Y * Y);
// 構造函數
public Point(int x, int y)
{
X = x;
Y = y;
}
// 方法
public void Translate(int dx, int dy)
{
X += dx;
Y += dy;
}
// 重寫 ToString
public override string ToString() => $"({X}, {Y})";
// 運算符重載
public static Point operator +(Point a, Point b)
{
return new Point(a.X + b.X, a.Y + b.Y);
}
public static Point operator -(Point a, Point b)
{
return new Point(a.X - b.X, a.Y - b.Y);
}
public static bool operator ==(Point a, Point b)
{
return a.X == b.X && a.Y == b.Y;
}
public static bool operator !=(Point a, Point b)
{
return !(a == b);
}
// 重寫 Equals 和 GetHashCode
public override bool Equals(object obj)
{
return obj is Point point && this == point;
}
public override int GetHashCode()
{
return HashCode.Combine(X, Y);
}
}
// 只讀結構 (C# 7.2+)
public readonly struct ReadOnlyPoint
{
public int X { get; }
public int Y { get; }
public ReadOnlyPoint(int x, int y)
{
X = x;
Y = y;
}
// 所有字段都必須在構造函數中初始化
// 不允許有非只讀的屬性或字段
}
// ref 結構 (C# 7.2+)
public ref struct RefPoint
{
public int X;
public int Y;
public RefPoint(int x, int y)
{
X = x;
Y = y;
}
// ref 結構不能實現接口或放在堆上
}
// 使用示例
class StructEnumDemo
{
public static void Demo()
{
// 枚舉使用
DayOfWeek today = DayOfWeek.Monday;
Console.WriteLine($"Today is {today} (value: {(int)today})");
// 枚舉轉換
string dayString = "Friday";
if (Enum.TryParse(dayString, out DayOfWeek parsedDay))
{
Console.WriteLine($"Parsed day: {parsedDay}");
}
// 標誌枚舉
FilePermissions permissions = FilePermissions.Read | FilePermissions.Write;
Console.WriteLine($"Permissions: {permissions}");
// 檢查標誌
if (permissions.HasFlag(FilePermissions.Read))
{
Console.WriteLine("Has read permission");
}
// 結構體使用
Point p1 = new Point(10, 20);
Point p2 = new Point(5, 15);
// 運算符重載
Point sum = p1 + p2;
Console.WriteLine($"p1 + p2 = {sum}");
// 結構體是值類型
Point p3 = p1; // 複製值
p3.X = 100;
Console.WriteLine($"p1.X = {p1.X}, p3.X = {p3.X}"); // 不同
// 比較
Console.WriteLine($"p1 == p2: {p1 == p2}");
// 使用 with 表達式創建修改的副本 (C# 9.0+ 用於結構體)
Point p4 = p1 with { X = 50 };
Console.WriteLine($"Modified copy: {p4}");
// 枚舉所有值
Console.WriteLine("\nAll days of week:");
foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
Console.WriteLine($"{day} = {(int)day}");
}
// 枚舉特性
var attributes = typeof(HttpStatusCode).GetCustomAttributes(false);
Console.WriteLine($"\nEnum type: {typeof(HttpStatusCode).Name}");
}
}
高級特性與委託
委託和事件
csharp
// 委託定義
public delegate void SimpleDelegate();
public delegate int CalculatorDelegate(int a, int b);
public delegate TResult GenericDelegate<T, TResult>(T arg);
public delegate void EventHandlerDelegate(object sender, EventArgs e);
// 自定義事件參數
public class TemperatureChangedEventArgs : EventArgs
{
public double OldTemperature { get; }
public double NewTemperature { get; }
public DateTime ChangeTime { get; }
public TemperatureChangedEventArgs(double oldTemp, double newTemp)
{
OldTemperature = oldTemp;
NewTemperature = newTemp;
ChangeTime = DateTime.Now;
}
}
// 事件發布者
public class Thermostat
{
private double _temperature;
// 定義事件 (使用 EventHandler 委託)
public event EventHandler<TemperatureChangedEventArgs> TemperatureChanged;
// 定義事件 (自定義委託)
public event EventHandlerDelegate OnTemperatureChanged;
public double Temperature
{
get => _temperature;
set
{
if (_temperature != value)
{
double oldTemp = _temperature;
_temperature = value;
// 觸發事件
OnTemperatureChanged?.Invoke(this, EventArgs.Empty);
TemperatureChanged?.Invoke(this,
new TemperatureChangedEventArgs(oldTemp, value));
}
}
}
}
// 事件訂閱者
public class TemperatureDisplay
{
public void Subscribe(Thermostat thermostat)
{
thermostat.TemperatureChanged += OnTemperatureChanged;
}
private void OnTemperatureChanged(object sender, TemperatureChangedEventArgs e)
{
Console.WriteLine($"Temperature changed from {e.OldTemperature}°C " +
$"to {e.NewTemperature}°C at {e.ChangeTime:HH:mm:ss}");
}
}
// 使用委託的類
public class MathOperations
{
public static int Add(int a, int b) => a + b;
public static int Subtract(int a, int b) => a - b;
public static int Multiply(int a, int b) => a * b;
public int Divide(int a, int b) => b != 0 ? a / b : 0;
}
// 委託和事件演示
class DelegateEventDemo
{
public static void Demo()
{
// 委託實例化
CalculatorDelegate addDelegate = MathOperations.Add;
CalculatorDelegate subtractDelegate = MathOperations.Subtract;
// 調用委託
int result = addDelegate(10, 5);
Console.WriteLine($"10 + 5 = {result}");
// 多播委託
CalculatorDelegate multiDelegate = addDelegate;
multiDelegate += subtractDelegate;
multiDelegate += MathOperations.Multiply;
// 多播委託調用所有方法,但只返回最後一個結果
int multiResult = multiDelegate(10, 5);
Console.WriteLine($"Multi-delegate result (last): {multiResult}");
// 獲取所有調用結果
Delegate[] delegates = multiDelegate.GetInvocationList();
foreach (CalculatorDelegate del in delegates)
{
Console.WriteLine($"Result: {del(10, 5)}");
}
// 匿名方法 (C# 2.0+)
CalculatorDelegate powerDelegate = delegate(int a, int b)
{
return (int)Math.Pow(a, b);
};
Console.WriteLine($"2^3 = {powerDelegate(2, 3)}");
// Lambda 表達式 (C# 3.0+)
CalculatorDelegate maxDelegate = (a, b) => a > b ? a : b;
CalculatorDelegate minDelegate = (a, b) =>
{
return a < b ? a : b;
};
// 泛型委託
GenericDelegate<string, int> stringLength = s => s.Length;
Console.WriteLine($"Length of 'Hello': {stringLength("Hello")}");
// 內置委託類型
Func<int, int, int> funcAdd = (a, b) => a + b;
Action<string> actionPrint = message => Console.WriteLine(message);
Predicate<int> isEven = n => n % 2 == 0;
Console.WriteLine($"Is 4 even? {isEven(4)}");
// 事件演示
Thermostat thermostat = new Thermostat();
TemperatureDisplay display = new TemperatureDisplay();
display.Subscribe(thermostat);
// 使用 Lambda 訂閱事件
thermostat.TemperatureChanged += (sender, e) =>
{
Console.WriteLine($"Lambda handler: Temp changed to {e.NewTemperature}°C");
};
// 觸發事件
thermostat.Temperature = 20.5;
thermostat.Temperature = 22.0;
// 取消訂閱
thermostat.TemperatureChanged -= display.OnTemperatureChanged;
// 事件訪問器
EventDemo eventDemo = new EventDemo();
eventDemo.MyEvent += () => Console.WriteLine("Event fired");
eventDemo.RaiseEvent();
}
}
// 自定義事件訪問器
public class EventDemo
{
private EventHandlerDelegate _myEvent;
public event EventHandlerDelegate MyEvent
{
add
{
Console.WriteLine("Adding event handler");
_myEvent += value;
}
remove
{
Console.WriteLine("Removing event handler");
_myEvent -= value;
}
}
public void RaiseEvent()
{
_myEvent?.Invoke(this, EventArgs.Empty);
}
}
匿名類型和動態類型
csharp
class AnonymousDynamicDemo
{
public static void Demo()
{
// 匿名類型 (C# 3.0+)
var person = new
{
Name = "John",
Age = 30,
Address = new { City = "New York", ZipCode = "10001" }
};
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
Console.WriteLine($"City: {person.Address.City}");
// 匿名類型是不可變的
// person.Name = "Jane"; // 編譯錯誤
// 匿名類型在 LINQ 中很有用
var people = new[]
{
new { Name = "Alice", Age = 25 },
new { Name = "Bob", Age = 30 },
new { Name = "Charlie", Age = 35 }
};
var youngPeople = people.Where(p => p.Age < 30)
.Select(p => new { p.Name, IsYoung = true });
foreach (var p in youngPeople)
{
Console.WriteLine($"{p.Name} is young: {p.IsYoung}");
}
// 動態類型 (C# 4.0+)
dynamic dynamicVariable = 10;
Console.WriteLine($"Type: {dynamicVariable.GetType()}, Value: {dynamicVariable}");
dynamicVariable = "Now I'm a string";
Console.WriteLine($"Type: {dynamicVariable.GetType()}, Value: {dynamicVariable}");
dynamicVariable = new { Property = "Value" };
Console.WriteLine($"Property: {dynamicVariable.Property}");
// 動態調用方法
dynamic math = new MathDynamic();
int sum = math.Add(5, 3);
Console.WriteLine($"Dynamic add: 5 + 3 = {sum}");
// 嘗試調用不存在的方法
try
{
math.NonExistentMethod();
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
{
Console.WriteLine($"Runtime error: {ex.Message}");
}
// ExpandoObject (動態對象)
dynamic expando = new System.Dynamic.ExpandoObject();
expando.Name = "Dynamic Object";
expando.Value = 42;
expando.Print = (Action)(() =>
{
Console.WriteLine($"Name: {expando.Name}, Value: {expando.Value}");
});
expando.Print();
// 動態對象作為字典
var dict = (IDictionary<string, object>)expando;
dict["NewProperty"] = "Added dynamically";
Console.WriteLine($"New property: {expando.NewProperty}");
// 與反射比較
object obj = new Person("Test", 20);
var type = obj.GetType();
var nameProperty = type.GetProperty("Name");
string name = (string)nameProperty.GetValue(obj);
// 使用動態更簡單
dynamic dynObj = obj;
string dynName = dynObj.Name;
}
}
public class MathDynamic
{
public int Add(int a, int b) => a + b;
public int Multiply(int a, int b) => a * b;
}
擴展方法
csharp
// 擴展方法必須在靜態類中定義
public static class StringExtensions
{
// 擴展 string 類型
public static bool IsNullOrEmpty(this string str)
{
return string.IsNullOrEmpty(str);
}
public static bool IsNullOrWhiteSpace(this string str)
{
return string.IsNullOrWhiteSpace(str);
}
public static string Reverse(this string str)
{
if (string.IsNullOrEmpty(str))
return str;
char[] charArray = str.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
public static string Truncate(this string str, int maxLength)
{
if (string.IsNullOrEmpty(str) || str.Length <= maxLength)
return str;
return str.Substring(0, maxLength) + "...";
}
public static bool IsPalindrome(this string str)
{
if (string.IsNullOrEmpty(str))
return false;
string clean = new string(str.Where(char.IsLetterOrDigit).ToArray())
.ToLower();
return clean == clean.Reverse();
}
// 為 IEnumerable<T> 擴展
public static string Join<T>(this IEnumerable<T> items, string separator)
{
return string.Join(separator, items);
}
}
// 為自定義類型添加擴展
public static class PersonExtensions
{
public static string GetFullInfo(this Person person)
{
return $"{person.Name}, {person.Age} years old";
}
public static bool IsTeenager(this Person person)
{
return person.Age >= 13 && person.Age <= 19;
}
}
// 為接口添加擴展
public static class CollectionExtensions
{
public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)
{
foreach (var item in items)
{
collection.Add(item);
}
}
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach (var item in collection)
{
action(item);
}
}
}
// 擴展方法演示
class ExtensionMethodDemo
{
public static void Demo()
{
// 使用字符串擴展方法
string text = "Hello World";
Console.WriteLine($"Original: {text}");
Console.WriteLine($"Reversed: {text.Reverse()}");
Console.WriteLine($"Truncated (5): {text.Truncate(5)}");
Console.WriteLine($"Is palindrome? {text.IsPalindrome()}");
Console.WriteLine($"Is 'racecar' palindrome? {"racecar".IsPalindrome()}");
// 使用集合擴展方法
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Console.WriteLine($"\nNumbers: {numbers.Join(", ")}");
numbers.ForEach(n => Console.WriteLine($"Number: {n}"));
// 添加多個項目
numbers.AddRange(new[] { 6, 7, 8 });
Console.WriteLine($"After AddRange: {numbers.Join(", ")}");
// 使用自定義類型擴展
Person person = new Person("Alice", 25);
Console.WriteLine($"\nPerson info: {person.GetFullInfo()}");
Console.WriteLine($"Is teenager? {person.IsTeenager()}");
// LINQ 本身就是擴展方法
var squares = numbers.Select(n => n * n);
Console.WriteLine($"Squares: {squares.Join(", ")}");
// 鏈式調用擴展方法
string result = numbers.Where(n => n % 2 == 0)
.Select(n => n.ToString())
.Join("|");
Console.WriteLine($"Even numbers: {result}");
// 為值類型添加擴展
int value = 42;
Console.WriteLine($"\nIs 42 even? {value.IsEven()}");
Console.WriteLine($"Square of 5: {5.Square()}");
}
}
// 值類型擴展
public static class IntExtensions
{
public static bool IsEven(this int number) => number % 2 == 0;
public static bool IsOdd(this int number) => !number.IsEven();
public static int Square(this int number) => number * number;
public static int Cube(this int number) => number * number * number;
public static int Factorial(this int number)
{
if (number <= 1) return 1;
return number * Factorial(number - 1);
}
public static string ToOrdinal(this int number)
{
if (number <= 0) return number.ToString();
switch (number % 100)
{
case 11:
case 12:
case 13:
return number + "th";
}
return (number % 10) switch
{
1 => number + "st",
2 => number + "nd",
3 => number + "rd",
_ => number + "th"
};
}
}
泛型與集合
泛型基礎
csharp
// 泛型類
public class GenericStack<T>
{
private T[] _items;
private int _top;
public GenericStack(int capacity = 10)
{
_items = new T[capacity];
_top = -1;
}
public void Push(T item)
{
if (_top == _items.Length - 1)
{
Array.Resize(ref _items, _items.Length * 2);
}
_items[++_top] = item;
}
public T Pop()
{
if (_top == -1)
throw new InvalidOperationException("Stack is empty");
return _items[_top--];
}
public T Peek()
{
if (_top == -1)
throw new InvalidOperationException("Stack is empty");
return _items[_top];
}
public bool IsEmpty => _top == -1;
public int Count => _top + 1;
// 泛型方法
public void ProcessItems<U>(U processor) where U : IItemProcessor<T>
{
for (int i = 0; i <= _top; i++)
{
processor.Process(_items[i]);
}
}
}
// 泛型接口
public interface IRepository<T> where T : class
{
void Add(T entity);
void Remove(T entity);
T GetById(int id);
IEnumerable<T> GetAll();
}
// 泛型約束
public class GenericRepository<T> : IRepository<T> where T : class, new()
{
private List<T> _items = new List<T>();
public void Add(T entity)
{
_items.Add(entity);
}
public void Remove(T entity)
{
_items.Remove(entity);
}
public T GetById(int id)
{
// 實際實現會根據 ID 查找
return _items.FirstOrDefault();
}
public IEnumerable<T> GetAll()
{
return _items;
}
// 創建新實例
public T Create()
{
return new T();
}
}
// 多個類型參數
public class KeyValuePair<K, V>
{
public K Key { get; set; }
public V Value { get; set; }
public KeyValuePair(K key, V value)
{
Key = key;
Value = value;
}
}
// 協變接口 (out)
public interface IReadOnlyRepository<out T> where T : class
{
T GetById(int id);
IEnumerable<T> GetAll();
}
// 逆變接口 (in)
public interface IComparator<in T>
{
int Compare(T x, T y);
}
// 泛型委託
public delegate T Transformer<T>(T input);
// 泛型演示
class GenericDemo
{
public static void Demo()
{
// 使用泛型類
GenericStack<int> intStack = new GenericStack<int>();
intStack.Push(1);
intStack.Push(2);
intStack.Push(3);
Console.WriteLine($"Stack count: {intStack.Count}");
Console.WriteLine($"Top item: {intStack.Peek()}");
Console.WriteLine($"Popped: {intStack.Pop()}");
GenericStack<string> stringStack = new GenericStack<string>();
stringStack.Push("Hello");
stringStack.Push("World");
// 泛型方法
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
List<string> strings = numbers.ConvertAll(n => n.ToString());
Console.WriteLine($"Converted strings: {string.Join(", ", strings)}");
// 泛型約束示例
GenericRepository<Person> personRepo = new GenericRepository<Person>();
personRepo.Add(new Person("Alice", 25));
// 創建新實例
Person newPerson = personRepo.Create();
newPerson.Name = "Bob";
newPerson.Age = 30;
personRepo.Add(newPerson);
// 泛型字典
Dictionary<string, Person> phoneBook = new Dictionary<string, Person>
{
["555-1234"] = new Person("John", 30),
["555-5678"] = new Person("Jane", 25)
};
// 添加和訪問
phoneBook["555-9999"] = new Person("Bob", 35);
if (phoneBook.TryGetValue("555-1234", out Person person))
{
Console.WriteLine($"Found: {person.Name}");
}
// 遍歷字典
foreach (var kvp in phoneBook)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value.Name}");
}
// 使用默認值
T GetDefault<T>() => default;
Console.WriteLine($"Default int: {GetDefault<int>()}");
Console.WriteLine($"Default string: {GetDefault<string>() ?? "null"}");
// 類型推斷
var pair = CreatePair("key", 123);
Console.WriteLine($"Pair: {pair.Key} = {pair.Value}");
// 泛型與繼承
NumericCalculator<int> intCalc = new NumericCalculator<int>();
Console.WriteLine($"Sum: {intCalc.Add(5, 3)}");
}
// 泛型方法
public static KeyValuePair<K, V> CreatePair<K, V>(K key, V value)
{
return new KeyValuePair<K, V>(key, value);
}
// 泛型與運算符
public static T Add<T>(T a, T b) where T : IAddable<T>
{
return a.Add(b);
}
}
// 用於演示的接口
public interface IItemProcessor<T>
{
void Process(T item);
}
// 用於約束的示例
public interface IAddable<T>
{
T Add(T other);
}
public class NumericCalculator<T> where T : IAddable<T>
{
public T Add(T a, T b) => a.Add(b);
}
集合框架
csharp
class CollectionsDemo
{
public static void Demo()
{
Console.WriteLine("=== List<T> ===");
// List<T> - 動態數組
List<string> fruits = new List<string> { "Apple", "Banana" };
fruits.Add("Cherry");
fruits.AddRange(new[] { "Date", "Elderberry" });
fruits.Insert(1, "Apricot");
fruits.Remove("Banana");
fruits.RemoveAt(0);
Console.WriteLine($"Count: {fruits.Count}");
Console.WriteLine($"Capacity: {fruits.Capacity}");
Console.WriteLine($"Contains 'Cherry': {fruits.Contains("Cherry")}");
Console.WriteLine($"Index of 'Date': {fruits.IndexOf("Date")}");
fruits.ForEach(f => Console.WriteLine($"- {f}"));
// 排序
List<int> numbers = new List<int> { 5, 2, 8, 1, 9 };
numbers.Sort();
Console.WriteLine($"Sorted: {string.Join(", ", numbers)}");
// 自定義排序
List<Person> people = new List<Person>
{
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
};
people.Sort((p1, p2) => p1.Age.CompareTo(p2.Age));
Console.WriteLine("\n=== Dictionary<TKey, TValue> ===");
// Dictionary<TKey, TValue> - 哈希表
Dictionary<string, int> wordCount = new Dictionary<string, int>
{
["hello"] = 1,
["world"] = 2
};
wordCount.Add("csharp", 3);
wordCount["dotnet"] = 4;
// 安全的訪問方式
if (wordCount.TryGetValue("hello", out int count))
{
Console.WriteLine($"'hello' count: {count}");
}
// 遍歷
foreach (var kvp in wordCount)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
// Keys 和 Values 集合
Console.WriteLine($"Keys: {string.Join(", ", wordCount.Keys)}");
Console.WriteLine($"Values: {string.Join(", ", wordCount.Values)}");
Console.WriteLine("\n=== HashSet<T> ===");
// HashSet<T> - 不重複的集合
HashSet<int> set1 = new HashSet<int> { 1, 2, 3, 4, 5 };
HashSet<int> set2 = new HashSet<int> { 4, 5, 6, 7, 8 };
set1.Add(6); // 添加已存在的元素會被忽略
Console.WriteLine($"Set1: {string.Join(", ", set1)}");
// 集合運算
var union = new HashSet<int>(set1);
union.UnionWith(set2);
Console.WriteLine($"Union: {string.Join(", ", union)}");
var intersection = new HashSet<int>(set1);
intersection.IntersectWith(set2);
Console.WriteLine($"Intersection: {string.Join(", ", intersection)}");
var except = new HashSet<int>(set1);
except.ExceptWith(set2);
Console.WriteLine($"Except: {string.Join(", ", except)}");
var symmetricExcept = new HashSet<int>(set1);
symmetricExcept.SymmetricExceptWith(set2);
Console.WriteLine($"Symmetric Except: {string.Join(", ", symmetricExcept)}");
Console.WriteLine("\n=== Queue<T> ===");
// Queue<T> - 先進先出
Queue<string> queue = new Queue<string>();
queue.Enqueue("First");
queue.Enqueue("Second");
queue.Enqueue("Third");
Console.WriteLine($"Count: {queue.Count}");
Console.WriteLine($"Peek: {queue.Peek()}");
while (queue.Count > 0)
{
Console.WriteLine($"Dequeued: {queue.Dequeue()}");
}
Console.WriteLine("\n=== Stack<T> ===");
// Stack<T> - 後進先出
Stack<string> stack = new Stack<string>();
stack.Push("First");
stack.Push("Second");
stack.Push("Third");
Console.WriteLine($"Count: {stack.Count}");
Console.WriteLine($"Peek: {stack.Peek()}");
while (stack.Count > 0)
{
Console.WriteLine($"Popped: {stack.Pop()}");
}
Console.WriteLine("\n=== LinkedList<T> ===");
// LinkedList<T> - 雙向鏈表
LinkedList<string> linkedList = new LinkedList<string>();
linkedList.AddLast("First");
linkedList.AddLast("Third");
LinkedListNode<string> node = linkedList.Find("Third");
if (node != null)
{
linkedList.AddBefore(node, "Second");
}
foreach (var item in linkedList)
{
Console.WriteLine($"Item: {item}");
}
// 遍歷節點
for (var currentNode = linkedList.First;
currentNode != null;
currentNode = currentNode.Next)
{
Console.WriteLine($"Node: {currentNode.Value}");
}
Console.WriteLine("\n=== Sorted Collections ===");
// SortedSet<T>
SortedSet<int> sortedSet = new SortedSet<int> { 5, 2, 8, 1, 9 };
Console.WriteLine($"SortedSet: {string.Join(", ", sortedSet)}");
Console.WriteLine($"Min: {sortedSet.Min}, Max: {sortedSet.Max}");
// SortedDictionary<TKey, TValue>
SortedDictionary<string, int> sortedDict = new SortedDictionary<string, int>
{
["zebra"] = 1,
["apple"] = 2,
["banana"] = 3
};
foreach (var kvp in sortedDict)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
Console.WriteLine("\n=== Concurrent Collections ===");
// 線程安全集合
var concurrentBag = new System.Collections.Concurrent.ConcurrentBag<int>();
var concurrentDict = new System.Collections.Concurrent.ConcurrentDictionary<string, int>();
var blockingCollection = new System.Collections.Concurrent.BlockingCollection<int>();
Console.WriteLine("\n=== ReadOnly Collections ===");
// 只讀視圖
List<int> originalList = new List<int> { 1, 2, 3, 4, 5 };
IReadOnlyList<int> readOnlyList = originalList.AsReadOnly();
// readOnlyList[0] = 10; // 編譯錯誤
originalList[0] = 10; // 這會影響 readOnlyList
Console.WriteLine($"ReadOnly list first item: {readOnlyList[0]}");
// 不可變集合 (需要 System.Collections.Immutable 包)
/*
var immutableList = System.Collections.Immutable.ImmutableList.Create(1, 2, 3);
var newList = immutableList.Add(4); // 返回新列表
*/
}
}
LINQ 查詢
LINQ 基礎
csharp
class LinqDemo
{
public static void Demo()
{
// 數據源
List<Person> people = new List<Person>
{
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 35),
new Person("David", 20),
new Person("Eve", 28),
new Person("Frank", 40)
};
List<Employee> employees = new List<Employee>
{
new Employee("Alice", "IT", 50000),
new Employee("Bob", "HR", 45000),
new Employee("Charlie", "IT", 60000),
new Employee("David", "Sales", 40000),
new Employee("Eve", "IT", 55000)
};
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Console.WriteLine("=== LINQ 查詢語法 ===");
// 查詢語法 (類似 SQL)
var query1 = from p in people
where p.Age > 25
orderby p.Name
select new { p.Name, p.Age };
foreach (var item in query1)
{
Console.WriteLine($"{item.Name}, {item.Age}");
}
Console.WriteLine("\n=== LINQ 方法語法 ===");
// 方法語法 (擴展方法)
var query2 = people
.Where(p => p.Age > 25)
.OrderBy(p => p.Name)
.Select(p => new { p.Name, p.Age });
foreach (var item in query2)
{
Console.WriteLine($"{item.Name}, {item.Age}");
}
Console.WriteLine("\n=== 過濾 (Where) ===");
var adults = people.Where(p => p.Age >= 18);
var evenNumbers = numbers.Where(n => n % 2 == 0);
Console.WriteLine($"Adults: {adults.Count()} people");
Console.WriteLine($"Even numbers: {string.Join(", ", evenNumbers)}");
// 多個條件
var filtered = people.Where(p => p.Age > 20 && p.Name.StartsWith("A"));
Console.WriteLine("\n=== 投影 (Select) ===");
var names = people.Select(p => p.Name);
var nameLengths = people.Select(p => new { p.Name, Length = p.Name.Length });
foreach (var item in nameLengths)
{
Console.WriteLine($"{item.Name}: {item.Length} chars");
}
// SelectMany - 展平嵌套集合
var departments = new List<Department>
{
new Department("IT", new[] { "Alice", "Bob" }),
new Department("HR", new[] { "Charlie", "David" })
};
var allEmployees = departments.SelectMany(d => d.Employees);
Console.WriteLine($"All employees: {string.Join(", ", allEmployees)}");
Console.WriteLine("\n=== 排序 (OrderBy) ===");
var sortedByName = people.OrderBy(p => p.Name);
var sortedByAgeDesc = people.OrderByDescending(p => p.Age);
var multiSorted = people.OrderBy(p => p.Name).ThenBy(p => p.Age);
Console.WriteLine("Sorted by name:");
foreach (var p in sortedByName)
{
Console.WriteLine($" {p.Name} ({p.Age})");
}
Console.WriteLine("\n=== 分組 (GroupBy) ===");
var groupedByFirstLetter = people.GroupBy(p => p.Name[0]);
foreach (var group in groupedByFirstLetter)
{
Console.WriteLine($"Group '{group.Key}':");
foreach (var person in group)
{
Console.WriteLine($" {person.Name}");
}
}
// 按年齡範圍分組
var ageGroups = people.GroupBy(p => p.Age / 10 * 10);
foreach (var group in ageGroups.OrderBy(g => g.Key))
{
Console.WriteLine($"Age {group.Key}-{group.Key + 9}: {group.Count()} people");
}
Console.WriteLine("\n=== 連接 (Join) ===");
var joinQuery = from p in people
join e in employees on p.Name equals e.Name
select new { p.Name, p.Age, e.Department, e.Salary };
foreach (var item in joinQuery)
{
Console.WriteLine($"{item.Name} ({item.Age}): {item.Department}, ${item.Salary}");
}
// 左外連接
var leftJoin = from p in people
join e in employees on p.Name equals e.Name into temp
from e in temp.DefaultIfEmpty()
select new
{
p.Name,
Department = e?.Department ?? "No Department",
Salary = e?.Salary ?? 0
};
Console.WriteLine("\n=== 分組連接 (GroupJoin) ===");
var groupJoin = from d in departments
join e in employees on d.Name equals e.Department into deptEmployees
select new { Department = d.Name, Employees = deptEmployees };
foreach (var dept in groupJoin)
{
Console.WriteLine($"{dept.Department}:");
foreach (var emp in dept.Employees)
{
Console.WriteLine($" {emp.Name}");
}
}
Console.WriteLine("\n=== 聚合函數 ===");
int totalAge = people.Sum(p => p.Age);
double averageAge = people.Average(p => p.Age);
int maxAge = people.Max(p => p.Age);
int minAge = people.Min(p => p.Age);
int count = people.Count();
int countAdults = people.Count(p => p.Age >= 18);
Console.WriteLine($"Total age: {totalAge}");
Console.WriteLine($"Average age: {averageAge:F2}");
Console.WriteLine($"Max age: {maxAge}");
Console.WriteLine($"Min age: {minAge}");
Console.WriteLine($"Total count: {count}");
Console.WriteLine($"Adults count: {countAdults}");
// Aggregate
string allNames = people.Aggregate("", (current, next) =>
current + (current == "" ? "" : ", ") + next.Name);
Console.WriteLine($"All names: {allNames}");
Console.WriteLine("\n=== 分頁 ===");
int pageSize = 2;
int pageNumber = 1;
var paged = people
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize);
Console.WriteLine($"Page {pageNumber}:");
foreach (var p in paged)
{
Console.WriteLine($" {p.Name}");
}
Console.WriteLine("\n=== 集合操作 ===");
List<int> setA = new List<int> { 1, 2, 3, 4, 5 };
List<int> setB = new List<int> { 4, 5, 6, 7, 8 };
var unionResult = setA.Union(setB);
var intersectResult = setA.Intersect(setB);
var exceptResult = setA.Except(setB);
var distinctNumbers = new[] { 1, 2, 2, 3, 3, 3 }.Distinct();
Console.WriteLine($"Union: {string.Join(", ", unionResult)}");
Console.WriteLine($"Intersection: {string.Join(", ", intersectResult)}");
Console.WriteLine($"Except: {string.Join(", ", exceptResult)}");
Console.WriteLine($"Distinct: {string.Join(", ", distinctNumbers)}");
Console.WriteLine("\n=== 元素操作 ===");
var first = people.First();
var firstOrDefault = people.FirstOrDefault(p => p.Age > 100);
var last = people.Last();
var single = people.Single(p => p.Name == "Alice");
var elementAt = people.ElementAt(2);
Console.WriteLine($"First: {first.Name}");
Console.WriteLine($"First or default (age > 100): {firstOrDefault?.Name ?? "null"}");
Console.WriteLine($"Last: {last.Name}");
Console.WriteLine($"Element at index 2: {elementAt.Name}");
Console.WriteLine("\n=== 判斷操作 ===");
bool anyAdults = people.Any(p => p.Age >= 18);
bool allAdults = people.All(p => p.Age >= 18);
bool containsAlice = people.Any(p => p.Name == "Alice");
Console.WriteLine($"Any adults: {anyAdults}");
Console.WriteLine($"All adults: {allAdults}");
Console.WriteLine($"Contains Alice: {containsAlice}");
Console.WriteLine("\n=== 轉換操作 ===");
List<Person> peopleList = people.ToList();
Person[] peopleArray = people.ToArray();
Dictionary<string, Person> peopleDict = people.ToDictionary(p => p.Name);
ILookup<char, Person> lookup = people.ToLookup(p => p.Name[0]);
Console.WriteLine($"List count: {peopleList.Count}");
Console.WriteLine($"Array length: {peopleArray.Length}");
Console.WriteLine($"Dictionary count: {peopleDict.Count}");
Console.WriteLine("\n=== 延遲執行 vs 立即執行 ===");
// 延遲執行
var deferred = people.Where(p => p.Age > 25);
people.Add(new Person("Grace", 45)); // 這會影響結果
Console.WriteLine("Deferred execution:");
foreach (var p in deferred)
{
Console.WriteLine($" {p.Name}");
}
// 立即執行
var immediate = people.Where(p => p.Age > 25).ToList();
people.Add(new Person("Henry", 50)); // 這不會影響結果
Console.WriteLine("Immediate execution:");
foreach (var p in immediate)
{
Console.WriteLine($" {p.Name}");
}
Console.WriteLine("\n=== 並行 LINQ (PLINQ) ===");
var parallelQuery = people.AsParallel()
.Where(p => p.Age > 25)
.OrderBy(p => p.Name);
foreach (var p in parallelQuery)
{
Console.WriteLine($"{p.Name} ({p.Age})");
}
}
}
// 輔助類
public class Employee
{
public string Name { get; set; }
public string Department { get; set; }
public decimal Salary { get; set; }
public Employee(string name, string department, decimal salary)
{
Name = name;
Department = department;
Salary = salary;
}
}
public class Department
{
public string Name { get; set; }
public string[] Employees { get; set; }
public Department(string name, string[] employees)
{
Name = name;
Employees = employees;
}
}
異步編程
async/await
csharp
class AsyncDemo
{
public static async Task Demo()
{
Console.WriteLine("=== 異步編程演示 ===\n");
// 基本異步方法
await BasicAsyncMethod();
// 返回值的異步方法
int result = await CalculateAsync(10, 20);
Console.WriteLine($"計算結果: {result}\n");
// 並行執行多個異步任務
await MultipleAsyncTasks();
// 異步流 (C# 8.0+)
await AsyncStreamDemo();
// 異步異常處理
await AsyncExceptionHandling();
// 取消令牌
await CancellationTokenDemo();
// 異步與同步的互操作
SyncOverAsyncWarning();
}
static async Task BasicAsyncMethod()
{
Console.WriteLine("開始異步操作...");
await Task.Delay(1000); // 模擬耗時操作
Console.WriteLine("異步操作完成!\n");
}
static async Task<int> CalculateAsync(int a, int b)
{
Console.WriteLine("開始計算...");
await Task.Delay(500); // 模擬計算時間
// 可以 await 其他異步方法
int intermediate = await ProcessAsync(a);
return intermediate + b;
}
static async Task<int> ProcessAsync(int value)
{
await Task.Delay(300);
return value * 2;
}
static async Task MultipleAsyncTasks()
{
Console.WriteLine("開始多個並行任務...");
var task1 = Task.Delay(1000).ContinueWith(_ => "任務1完成");
var task2 = Task.Delay(800).ContinueWith(_ => "任務2完成");
var task3 = Task.Delay(1200).ContinueWith(_ => "任務3完成");
// 等待所有任務完成
var results = await Task.WhenAll(task1, task2, task3);
Console.WriteLine($"所有任務完成: {string.Join(", ", results)}\n");
// 等待任何一個任務完成
var tasks = new[]
{
Task.Delay(1500).ContinueWith(_ => "慢任務"),
Task.Delay(500).ContinueWith(_ => "快任務")
};
var firstResult = await Task.WhenAny(tasks);
Console.WriteLine($"第一個完成的任務: {await firstResult}\n");
}
// 異步流 (C# 8.0+)
static async Task AsyncStreamDemo()
{
Console.WriteLine("開始異步流...");
await foreach (var number in GenerateNumbersAsync())
{
Console.WriteLine($"收到: {number}");
}
Console.WriteLine();
}
static async IAsyncEnumerable<int> GenerateNumbersAsync()
{
for (int i = 1; i <= 5; i++)
{
await Task.Delay(200); // 模擬異步操作
yield return i;
}
}
static async Task AsyncExceptionHandling()
{
Console.WriteLine("異步異常處理演示...");
try
{
await TaskThatThrowsAsync();
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"捕獲到異常: {ex.Message}");
}
// 多個任務的異常處理
var task1 = TaskThatThrowsAsync("任務1");
var task2 = TaskThatThrowsAsync("任務2");
var allTasks = Task.WhenAll(task1, task2);
try
{
await allTasks;
}
catch
{
// 處理 AggregateException
if (allTasks.Exception != null)
{
Console.WriteLine($"總共 {allTasks.Exception.InnerExceptions.Count} 個異常:");
foreach (var ex in allTasks.Exception.InnerExceptions)
{
Console.WriteLine($" - {ex.Message}");
}
}
}
Console.WriteLine();
}
static async Task TaskThatThrowsAsync(string taskName = "默認任務")
{
await Task.Delay(100);
throw new InvalidOperationException($"{taskName} 拋出異常");
}
static async Task CancellationTokenDemo()
{
Console.WriteLine("取消令牌演示...");
var cts = new CancellationTokenSource();
cts.CancelAfter(1500); // 1.5秒後自動取消
try
{
await LongRunningTaskAsync(cts.Token);
Console.WriteLine("任務正常完成");
}
catch (OperationCanceledException)
{
Console.WriteLine("任務被取消");
}
catch (Exception ex)
{
Console.WriteLine($"其他異常: {ex.Message}");
}
Console.WriteLine();
}
static async Task LongRunningTaskAsync(CancellationToken cancellationToken)
{
for (int i = 0; i < 10; i++)
{
cancellationToken.ThrowIfCancellationRequested();
Console.WriteLine($"進度: {i + 1}/10");
await Task.Delay(500, cancellationToken);
}
}
static void SyncOverAsyncWarning()
{
Console.WriteLine("=== 同步上下文警告 ===");
Console.WriteLine("避免在同步方法中調用異步方法時使用 .Result 或 .Wait()");
Console.WriteLine("這可能導致死鎖!\n");
// 錯誤示例(可能導致死鎖)
// var result = SomeAsyncMethod().Result;
// 正確做法:使用 async/await 貫穿整個調用鏈
}
// 異步屬性示例 (C# 8.0+ 不直接支持,但可以通過方法模擬)
public async Task<string> GetDataAsync()
{
await Task.Delay(100);
return "異步數據";
}
}
// 異步模式實現
public class AsyncDataLoader
{
// 傳統的 APM 模式 (Asynchronous Programming Model)
public IAsyncResult BeginLoadData(AsyncCallback callback, object state)
{
var task = LoadDataAsync();
return task.AsAsyncResult(callback, state);
}
public string EndLoadData(IAsyncResult asyncResult)
{
return ((Task<string>)asyncResult).Result;
}
// 基於事件的異步模式 (EAP)
public event EventHandler<DataLoadedEventArgs> DataLoaded;
public void LoadDataAsyncEAP()
{
Task.Run(async () =>
{
try
{
var data = await LoadDataAsync();
DataLoaded?.Invoke(this, new DataLoadedEventArgs(data));
}
catch (Exception ex)
{
DataLoaded?.Invoke(this, new DataLoadedEventArgs(null, ex));
}
});
}
// 現代的 TAP 模式 (Task-based Asynchronous Pattern)
public async Task<string> LoadDataAsync()
{
await Task.Delay(1000);
return "加載的數據";
}
}
public class DataLoadedEventArgs : EventArgs
{
public string Data { get; }
public Exception Error { get; }
public DataLoadedEventArgs(string data, Exception error = null)
{
Data = data;
Error = error;
}
}
// 異步 Dispose 模式
public class AsyncResource : IAsyncDisposable, IDisposable
{
private bool _disposed = false;
public async ValueTask DisposeAsync()
{
await DisposeAsyncCore();
Dispose(false);
GC.SuppressFinalize(this);
}
protected virtual async ValueTask DisposeAsyncCore()
{
// 異步清理資源
await Task.Delay(100); // 模擬異步清理
Console.WriteLine("資源已異步清理");
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// 同步清理托管資源
}
// 清理非托管資源
_disposed = true;
}
}
~AsyncResource()
{
Dispose(false);
}
}
屬性與反射
csharp
// 自定義屬性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method |
AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public class CustomAttribute : Attribute
{
public string Description { get; }
public int Priority { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public CustomAttribute(string description)
{
Description = description;
Date = DateTime.Now;
}
}
// 另一個自定義屬性
[AttributeUsage(AttributeTargets.Property)]
public class ValidationAttribute : Attribute
{
public int MinLength { get; set; }
public int MaxLength { get; set; }
public bool Required { get; set; }
}
// 使用自定義屬性的類
[Custom("這是一個業務邏輯類", Author = "John Doe", Priority = 1)]
[Serializable]
public class Product
{
[Validation(Required = true, MinLength = 3, MaxLength = 50)]
public string Name { get; set; }
[Validation(Required = true)]
[Obsolete("請使用 DecimalPrice 屬性")]
public double Price { get; set; }
public decimal DecimalPrice { get; set; }
[Custom("這是庫存屬性")]
public int Stock { get; set; }
[Custom("計算折扣價格的方法", Priority = 2)]
public decimal CalculateDiscount(decimal discountRate)
{
return DecimalPrice * (1 - discountRate);
}
}
// 反射演示
class ReflectionDemo
{
public static void Demo()
{
Console.WriteLine("=== 反射基礎 ===\n");
Type productType = typeof(Product);
// 獲取類型信息
Console.WriteLine($"類型名稱: {productType.Name}");
Console.WriteLine($"全名: {productType.FullName}");
Console.WriteLine($"命名空間: {productType.Namespace}");
Console.WriteLine($"是否是類: {productType.IsClass}");
Console.WriteLine($"是否是值類型: {productType.IsValueType}");
Console.WriteLine($"基類型: {productType.BaseType?.Name}");
// 獲取屬性
Console.WriteLine("\n=== 屬性信息 ===");
var properties = productType.GetProperties(
BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in properties)
{
Console.WriteLine($"屬性: {prop.Name}");
Console.WriteLine($" 類型: {prop.PropertyType.Name}");
Console.WriteLine($" 可讀: {prop.CanRead}");
Console.WriteLine($" 可寫: {prop.CanWrite}");
// 獲取屬性上的特性
var attributes = prop.GetCustomAttributes();
foreach (var attr in attributes)
{
Console.WriteLine($" 特性: {attr.GetType().Name}");
if (attr is ValidationAttribute validationAttr)
{
Console.WriteLine($" Required: {validationAttr.Required}");
Console.WriteLine($" MinLength: {validationAttr.MinLength}");
Console.WriteLine($" MaxLength: {validationAttr.MaxLength}");
}
}
}
// 獲取方法
Console.WriteLine("\n=== 方法信息 ===");
var methods = productType.GetMethods(
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var method in methods)
{
Console.WriteLine($"方法: {method.Name}");
Console.WriteLine($" 返回類型: {method.ReturnType.Name}");
var parameters = method.GetParameters();
if (parameters.Length > 0)
{
Console.WriteLine($" 參數:");
foreach (var param in parameters)
{
Console.WriteLine($" {param.ParameterType.Name} {param.Name}");
}
}
}
// 獲取特性
Console.WriteLine("\n=== 類型特性 ===");
var typeAttributes = productType.GetCustomAttributes();
foreach (var attr in typeAttributes)
{
Console.WriteLine($"特性: {attr.GetType().Name}");
if (attr is CustomAttribute customAttr)
{
Console.WriteLine($" 描述: {customAttr.Description}");
Console.WriteLine($" 作者: {customAttr.Author}");
Console.WriteLine($" 優先級: {customAttr.Priority}");
Console.WriteLine($" 日期: {customAttr.Date}");
}
}
// 動態創建實例
Console.WriteLine("\n=== 動態創建實例 ===");
object productInstance = Activator.CreateInstance(productType);
// 動態設置屬性
PropertyInfo nameProperty = productType.GetProperty("Name");
nameProperty.SetValue(productInstance, "筆記本電腦");
PropertyInfo priceProperty = productType.GetProperty("DecimalPrice");
priceProperty.SetValue(productInstance, 2999.99m);
// 動態讀取屬性
string name = (string)nameProperty.GetValue(productInstance);
decimal price = (decimal)priceProperty.GetValue(productInstance);
Console.WriteLine($"產品: {name}, 價格: {price:C}");
// 動態調用方法
Console.WriteLine("\n=== 動態調用方法 ===");
MethodInfo discountMethod = productType.GetMethod("CalculateDiscount");
object discountResult = discountMethod.Invoke(productInstance, new object[] { 0.1m });
Console.WriteLine($"折扣後價格: {discountResult:C}");
// 使用 dynamic 關鍵字
Console.WriteLine("\n=== 使用 dynamic ===");
dynamic dynamicProduct = Activator.CreateInstance(productType);
dynamicProduct.Name = "智能手機";
dynamicProduct.DecimalPrice = 1999.99m;
decimal dynamicDiscount = dynamicProduct.CalculateDiscount(0.15m);
Console.WriteLine($"動態產品折扣: {dynamicDiscount:C}");
// 程序集操作
Console.WriteLine("\n=== 程序集信息 ===");
Assembly currentAssembly = Assembly.GetExecutingAssembly();
Console.WriteLine($"程序集名稱: {currentAssembly.GetName().Name}");
Console.WriteLine($"版本: {currentAssembly.GetName().Version}");
// 獲取程序集中的所有類型
var allTypes = currentAssembly.GetTypes();
Console.WriteLine($"程序集中類型數量: {allTypes.Length}");
// 查找實現特定接口的類型
var serializableTypes = allTypes.Where(t =>
t.GetCustomAttribute<SerializableAttribute>() != null);
Console.WriteLine($"可序列化類型: {serializableTypes.Count()}");
// 特性驗證示例
Console.WriteLine("\n=== 特性驗證 ===");
Product testProduct = new Product();
ValidateProduct(testProduct);
testProduct.Name = "AB"; // 太短
ValidateProduct(testProduct);
testProduct.Name = "有效的產品名稱";
ValidateProduct(testProduct);
}
static void ValidateProduct(Product product)
{
var properties = typeof(Product).GetProperties();
foreach (var property in properties)
{
var validationAttr = property.GetCustomAttribute<ValidationAttribute>();
if (validationAttr != null)
{
object value = property.GetValue(product);
if (validationAttr.Required && value == null)
{
Console.WriteLine($"{property.Name}: 必須提供值");
}
if (value is string stringValue)
{
if (stringValue.Length < validationAttr.MinLength)
{
Console.WriteLine($"{property.Name}: 長度不能少於 {validationAttr.MinLength}");
}
if (stringValue.Length > validationAttr.MaxLength && validationAttr.MaxLength > 0)
{
Console.WriteLine($"{property.Name}: 長度不能超過 {validationAttr.MaxLength}");
}
}
}
}
}
}
// 表達式樹
class ExpressionTreeDemo
{
public static void Demo()
{
Console.WriteLine("=== 表達式樹 ===\n");
// 創建表達式: x => x * 2
ParameterExpression parameter = Expression.Parameter(typeof(int), "x");
ConstantExpression constant = Expression.Constant(2, typeof(int));
BinaryExpression multiply = Expression.Multiply(parameter, constant);
LambdaExpression lambda = Expression.Lambda<Func<int, int>>(multiply, parameter);
// 編譯表達式
Func<int, int> func = (Func<int, int>)lambda.Compile();
// 執行
int result = func(5);
Console.WriteLine($"5 * 2 = {result}");
// 動態構建複雜表達式
Console.WriteLine("\n=== 動態構建查詢表達式 ===");
// 構建: x => x > 5 && x < 10
ParameterExpression param = Expression.Parameter(typeof(int), "x");
ConstantExpression five = Expression.Constant(5, typeof(int));
ConstantExpression ten = Expression.Constant(10, typeof(int));
BinaryExpression greaterThan = Expression.GreaterThan(param, five);
BinaryExpression lessThan = Expression.LessThan(param, ten);
BinaryExpression and = Expression.AndAlso(greaterThan, lessThan);
LambdaExpression lambda2 = Expression.Lambda<Func<int, bool>>(and, param);
Func<int, bool> filter = (Func<int, bool>)lambda2.Compile();
// 測試
int[] numbers = { 1, 3, 5, 7, 9, 11 };
var filtered = numbers.Where(filter);
Console.WriteLine($"過濾結果: {string.Join(", ", filtered)}");
// 屬性訪問表達式
Console.WriteLine("\n=== 屬性訪問表達式 ===");
ParameterExpression productParam = Expression.Parameter(typeof(Product), "p");
MemberExpression nameProperty = Expression.Property(productParam, "Name");
ConstantExpression searchValue = Expression.Constant("筆記本", typeof(string));
MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
MethodCallExpression containsCall = Expression.Call(nameProperty, containsMethod, searchValue);
LambdaExpression searchLambda = Expression.Lambda<Func<Product, bool>>(containsCall, productParam);
Func<Product, bool> searchFunc = (Func<Product, bool>)searchLambda.Compile();
// 這只是演示,實際使用時會配合數據源
}
}
C# 新特性
C# 8.0-12.0 新特性
csharp
class CSharpNewFeatures
{
public static void Demo()
{
Console.WriteLine("=== C# 8.0-12.0 新特性演示 ===\n");
// 1. 可空引用類型 (C# 8.0)
NullableReferenceTypes();
// 2. 模式匹配增強 (C# 8.0, 9.0, 11.0)
PatternMatching();
// 3. 索引和範圍 (C# 8.0)
IndicesAndRanges();
// 4. 默認接口方法 (C# 8.0)
DefaultInterfaceMethods();
// 5. 記錄類型 (C# 9.0)
RecordTypes();
// 6. 僅初始化屬性 (C# 9.0)
InitOnlyProperties();
// 7. 頂層語句 (C# 9.0)
// 注意:這主要在 Program.cs 中使用
// 8. 模式匹配增強 (C# 9.0)
EnhancedPatternMatching();
// 9. 目標類型 new 表達式 (C# 9.0)
TargetTypedNew();
// 10. 全局 using 語句 (C# 10.0)
// 在文件頂部使用:global using System;
// 11. 文件範圍的命名空間 (C# 10.0)
// namespace MyNamespace; // 不需要大括號
// 12. 原始字符串字面量 (C# 11.0)
RawStringLiterals();
// 13. 泛型屬性 (C# 11.0)
GenericAttributes();
// 14. 必需的成員 (C# 11.0)
RequiredMembers();
// 15. 列表模式 (C# 11.0)
ListPatterns();
// 16. 主構造函數 (C# 12.0)
PrimaryConstructors();
// 17. 集合表達式 (C# 12.0)
CollectionExpressions();
// 18. 默認 Lambda 參數 (C# 12.0)
DefaultLambdaParameters();
}
static void NullableReferenceTypes()
{
Console.WriteLine("1. 可空引用類型 (C# 8.0):");
// 啟用可空引用類型後,引用類型默認不可為空
string nonNullable = "Hello"; // 正常
// string nullString = null; // 警告
// 明確聲明可空
string? nullableString = null; // 正常
// 空容許上下文
#nullable disable
string disabledNullable = null; // 沒有警告
#nullable restore
Console.WriteLine(" 可空引用類型已啟用\n");
}
static void PatternMatching()
{
Console.WriteLine("2. 模式匹配增強:");
object obj = "Hello";
// 屬性模式 (C# 8.0)
if (obj is string { Length: > 3 } s)
{
Console.WriteLine($" 長字符串: {s}");
}
// 元組模式 (C# 8.0)
var point = (5, 10);
var result = point switch
{
(0, 0) => "原點",
(var x, var y) when x == y => "對角線",
(_, _) => "其他點"
};
Console.WriteLine($" 元組模式: {result}");
// 位置模式 (C# 8.0)
var shape = new Rectangle(10, 20);
if (shape is (10, 20))
{
Console.WriteLine($" 匹配的矩形: 10x20");
}
Console.WriteLine();
}
static void IndicesAndRanges()
{
Console.WriteLine("3. 索引和範圍 (C# 8.0):");
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// ^ 運算符表示從末尾開始
int last = numbers[^1]; // 9
int secondLast = numbers[^2]; // 8
// .. 運算符表示範圍
var slice1 = numbers[1..4]; // [1, 2, 3]
var slice2 = numbers[..3]; // [0, 1, 2]
var slice3 = numbers[6..]; // [6, 7, 8, 9]
var slice4 = numbers[..]; // 全部
var slice5 = numbers[^3..]; // [7, 8, 9]
Console.WriteLine($" 最後一個: {last}");
Console.WriteLine($" 倒數第二個: {secondLast}");
Console.WriteLine($" 範圍 1..4: {string.Join(", ", slice1)}");
Console.WriteLine();
}
static void DefaultInterfaceMethods()
{
Console.WriteLine("4. 默認接口方法 (C# 8.0):");
ILogger logger = new ConsoleLogger();
logger.Log("信息"); // 調用默認實現
logger.LogError("錯誤"); // 調用重寫實現
Console.WriteLine();
}
static void RecordTypes()
{
Console.WriteLine("5. 記錄類型 (C# 9.0):");
// 記錄類型 - 不可變數據類型
var person1 = new PersonRecord("Alice", 25);
var person2 = new PersonRecord("Alice", 25);
// 值相等性
Console.WriteLine($" person1 == person2: {person1 == person2}");
// with 表達式創建修改的副本
var person3 = person1 with { Age = 26 };
Console.WriteLine($" 修改後的副本: {person3}");
// 解構
var (name, age) = person1;
Console.WriteLine($" 解構: {name}, {age}");
// 位置記錄
var point = new PointRecord(10, 20);
Console.WriteLine($" 位置記錄: {point}");
Console.WriteLine();
}
static void InitOnlyProperties()
{
Console.WriteLine("6. 僅初始化屬性 (C# 9.0):");
var config = new AppConfig
{
Name = "MyApp",
Version = "1.0.0"
// 初始化後不能再修改
};
// config.Name = "NewName"; // 編譯錯誤
Console.WriteLine($" 配置: {config.Name} v{config.Version}\n");
}
static void EnhancedPatternMatching()
{
Console.WriteLine("8. 增強的模式匹配 (C# 9.0):");
// 關係模式
int score = 85;
var grade = score switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
Console.WriteLine($" 分數 {score} => 等級 {grade}");
// 邏輯模式
object value = 42;
if (value is not null and int n)
{
Console.WriteLine($" 不是 null 且是整數: {n}");
}
Console.WriteLine();
}
static void TargetTypedNew()
{
Console.WriteLine("9. 目標類型 new 表達式 (C# 9.0):");
// 不需要重複類型
Person person = new("Bob", 30);
List<string> names = new() { "Alice", "Bob", "Charlie" };
Console.WriteLine($" 創建對象: {person.Name}\n");
}
static void RawStringLiterals()
{
Console.WriteLine("12. 原始字符串字面量 (C# 11.0):");
string json = """
{
"name": "Alice",
"age": 30,
"address": "123 Main St"
}
""";
Console.WriteLine($" JSON 字符串:\n{json}\n");
// 帶插值的原始字符串
string name = "Alice";
string interpolated = $"""
你好 {name}!
這是一個多行
原始字符串。
""";
Console.WriteLine(interpolated + "\n");
}
static void GenericAttributes()
{
Console.WriteLine("13. 泛型屬性 (C# 11.0):");
// 之前: [Custom(typeof(MyClass))]
// 現在: [Custom<MyClass>]
Console.WriteLine(" 泛型屬性現在可以直接使用\n");
}
static void RequiredMembers()
{
Console.WriteLine("14. 必需的成員 (C# 11.0):");
// 使用 required 關鍵字
var user = new User
{
Username = "alice", // 必須初始化
Email = "alice@example.com" // 必須初始化
};
Console.WriteLine($" 用戶: {user.Username}\n");
}
static void ListPatterns()
{
Console.WriteLine("15. 列表模式 (C# 11.0):");
int[] numbers = { 1, 2, 3, 4, 5 };
if (numbers is [1, 2, .., 5])
{
Console.WriteLine(" 匹配列表模式 [1, 2, .., 5]");
}
// 切片模式
var result = numbers switch
{
[] => "空數組",
[1] => "只有 1",
[1, 2] => "1, 2",
[1, .. var middle, 5] => $"以 1 開始,5 結束,中間有 {middle.Length} 個元素",
_ => "其他"
};
Console.WriteLine($" 結果: {result}\n");
}
static void PrimaryConstructors()
{
Console.WriteLine("16. 主構造函數 (C# 12.0):");
var student = new Student("Alice", 20);
Console.WriteLine($" 學生: {student.Name}, {student.Age}歲\n");
}
static void CollectionExpressions()
{
Console.WriteLine("17. 集合表達式 (C# 12.0):");
// 統一語法
int[] array1 = [1, 2, 3, 4, 5];
List<int> list1 = [1, 2, 3, 4, 5];
Span<int> span1 = [1, 2, 3, 4, 5];
// 展開運算符
int[] part1 = [1, 2, 3];
int[] part2 = [4, 5, 6];
int[] combined = [.. part1, .. part2];
Console.WriteLine($" 合併數組: {string.Join(", ", combined)}\n");
}
static void DefaultLambdaParameters()
{
Console.WriteLine("18. 默認 Lambda 參數 (C# 12.0):");
var addWithDefault = (int x, int y = 1) => x + y;
Console.WriteLine($" 默認參數 Lambda: addWithDefault(5) = {addWithDefault(5)}");
Console.WriteLine($" addWithDefault(5, 3) = {addWithDefault(5, 3)}\n");
}
}
// 記錄類型定義
public record PersonRecord(string Name, int Age);
public record PointRecord(int X, int Y)
{
public double Distance => Math.Sqrt(X * X + Y * Y);
}
// 僅初始化屬性
public class AppConfig
{
public string Name { get; init; }
public string Version { get; init; }
}
// 默認接口方法
public interface ILogger
{
void Log(string message)
{
Console.WriteLine($" 日誌: {message}");
}
void LogError(string error);
}
public class ConsoleLogger : ILogger
{
public void LogError(string error)
{
Console.WriteLine($" 錯誤: {error}");
}
}
// 必需的成員
public class User
{
public required string Username { get; init; }
public required string Email { get; init; }
public string? Phone { get; init; }
}
// 主構造函數 (C# 12.0)
public class Student(string name, int age)
{
public string Name { get; } = name;
public int Age { get; } = age;
// 可以在類體中使用主構造函數參數
public string Info => $"{Name} ({Age})";
}
總結
C# 是一門功能豐富、不斷發展的現代編程語言。從基礎的語法和數據類型,到面向對象編程、泛型、LINQ、異步編程,再到最新的語言特性,C# 提供了強大的工具來構建各種類型的應用程序。
C# 的主要優勢:
-
類型安全:強類型系統幫助在編譯時捕獲錯誤
-
面向對象:完整的 OOP 支持
-
現代語法:不斷引入新特性保持語言的現代性
-
強大的框架:.NET 框架提供了豐富的庫
-
跨平台:.NET Core/.NET 5+ 支持跨平台開發
-
性能優秀:編譯為本地代碼,性能接近 C++
學習建議:
-
掌握基礎:深入理解類型系統、OOP 概念
-
熟悉框架:學習 .NET 標準庫和常用框架
-
實踐項目:通過實際項目應用所學知識
-
關注發展:關注 C# 和 .NET 的新特性
-
閱讀源碼:閱讀優秀開源項目的源代碼
C# 的學習曲線相對平緩,但深度很大。隨著經驗的積累,你會發現這門語言能夠優雅地解決複雜的問題,是企業級應用開發的優秀選擇。
版權聲明:本文檔僅供學習參考,代碼示例可以自由使用和修改。部分高級特性可能需要特定版本的 .NET SDK 支持。
更多推荐




所有评论(0)