C# 基础语法

3 minBeginner2026/6/14

变量与类型、值类型与引用类型、字符串插值、模式匹配、控制流、nullable 引用类型、顶级语句

1. 变量与

1.1 内置

C# 提供丰富的内置型,所有型都继承自 System.Object

C# .NET 大小范围
boolSystem.Boolean1 字节true / false
byteSystem.Byte1 字节0 ~ 255
sbyteSystem.SByte1 字节-128 ~ 127
shortSystem.Int162 字节-32768 ~ 32767
intSystem.Int324 字节-2³¹ ~ 2³¹-1
longSystem.Int648 字节-2⁶³ ~ 2⁶³-1
floatSystem.Single4 字节±1.5×10⁻⁴⁵ ~ ±3.4×10³⁸
doubleSystem.Double8 字节±5.0×10⁻³²⁴ ~ ±1.7×10³⁰⁸
decimalSystem.Decimal16 字节±1.0×10⁻²⁸ ~ ±7.9×10²⁸
charSystem.Char2 字节U+0000 ~ U+FFFF
stringSystem.String引用Unicode 字符序列
nintSystem.IntPtr平台相关本机整数
Int128System.Int12816 字节.NET 8+ 128位整数

1.2 变量声明

// 显式类型
int age = 25;
string name = "张三";
double price = 99.99;
bool isActive = true;

// var 类型推断(编译期确定类型)
var count = 42;           // int
var message = "Hello";    // string
var numbers = new[] { 1, 2, 3 }; // int[]
var dict = new Dictionary<string, int>(); // Dictionary<string, int>

// 常量
const double Pi = 3.14159265358979;
const string AppName = "FANDEX";

// C# 11 required 修饰符
public class Person
{
    public required string Name { get; init; }
    public required int Age { get; init; }
}

var person = new Person { Name = "李四", Age = 30 }; // 必须初始化

1.3 型转换

// 隐式转换(安全,无数据丢失)
int num = 100;
long bigNum = num;        // int → long
double d = num;           // int → double

// 显式转换(可能丢失数据)
double pi = 3.14159;
int intPi = (int)pi;      // 3,截断小数部分

// 使用 Convert 类
string str = "123";
int parsed = Convert.ToInt32(str);
double dbl = Convert.ToDouble("3.14");

// 使用 Parse / TryParse
int number = int.Parse("456");

if (int.TryParse("789", out int result))
{
    Console.WriteLine($"解析成功: {result}");
}

// 安全的类型转换 (is / as)
object obj = "Hello";
if (obj is string s)
{
    Console.WriteLine(s.Length); // 5
}

IAnimal? animal = dog as IAnimal; // 失败返回 null

2. 值型与引用

2.1 核心区别

特性引用
存储位置栈(通常)
赋值行为复制值复制引用
默认值0 / falsenull
继承继承自 System.ValueType继承自 System.Object
示例int, double, bool, struct, enumclass, string, array, delegate
// 值类型 - 复制值
int a = 10;
int b = a;    // b 得到 a 的副本
b = 20;       // 不影响 a
Console.WriteLine(a); // 10

// 引用类型 - 复制引用
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;    // list2 指向同一对象
list2.Add(4);
Console.WriteLine(list1.Count); // 4,list1 也受影响

// struct 是值类型
public struct Point
{
    public double X { get; set; }
    public double Y { get; set; }

    public double Distance => Math.Sqrt(X * X + Y * Y);
}

// readonly struct(不可变值类型)
public readonly struct Money
{
    public decimal Amount { get; init; }
    public string Currency { get; init; }
}

2.2 装箱与拆箱

// 装箱:值类型 → 引用类型(分配堆内存)
int value = 42;
object boxed = value; // 装箱

// 拆箱:引用类型 → 值类型
int unboxed = (int)boxed; // 拆箱

// 避免频繁装箱,使用泛型
// 不好的做法
ArrayList list = new(); // 每次添加 int 都会装箱
list.Add(1);

// 好的做法
List<int> genericList = new(); // 无装箱
genericList.Add(1);

3. 字符串操作

3.1 字符串插值

var name = "世界";
var year = 2026;

// 基本插值
Console.WriteLine($"你好, {name}! 当前年份: {year}");

// 表达式插值
Console.WriteLine($"2 + 3 = {2 + 3}");
Console.WriteLine($"大写: {name.ToUpper()}");
Console.WriteLine($"时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");

// C# 11 原始字符串字面量
var json = """
    {
        "name": "张三",
        "age": 25,
        "email": "zhangsan@example.com"
    }
    """;

// 插值原始字符串
var id = 1001;
var query = $"""
    SELECT * FROM Users
    WHERE Id = {id}
    AND IsActive = 1
    """;

3.2 常用字符串操作

string str = "Hello, C# World!";

// 查找
bool contains = str.Contains("C#");         // true
int index = str.IndexOf("World");           // 9
bool startsWith = str.StartsWith("Hello");  // true

// 截取与分割
string sub = str.Substring(7, 2);           // "C#"
string[] parts = str.Split(' ');            // ["Hello,", "C#", "World!"]

// 修改
string upper = str.ToUpper();               // "HELLO, C# WORLD!"
string trimmed = "  hello  ".Trim();        // "hello"
string replaced = str.Replace("C#", "F#");  // "Hello, F# World!"

// 字符串构建(高性能拼接)
var sb = new StringBuilder();
sb.AppendLine("第一行");
sb.AppendLine("第二行");
sb.AppendFormat("数字: {0:N2}", 1234.5678);
string result = sb.ToString();

4. Nullable 引用

C# 8.0 引入的可空引用型是重要的型安全增强,新项目默认启用:

#nullable enable

// 引用类型默认不可为 null
string name = "张三";   // OK
// string name2 = null; // 警告!

// 使用 ? 标记可为 null
string? nickname = null; // OK,无警告

// 访问前需要 null 检查
if (nickname is not null)
{
    Console.WriteLine(nickname.Length); // 安全
}

// 空条件运算符
int? length = nickname?.Length;     // null 如果 nickname 为 null
string upper = nickname?.ToUpper(); // null 如果 nickname 为 null

// 空合并运算符
string display = nickname ?? "匿名";       // null 时使用默认值
string display2 = nickname ??= "匿名";     // null 时赋值并返回

// 强制非空(慎用!)
string forced = nickname!; // 告诉编译器"我确定不为 null"

// 值类型可空
int? age = null;            // Nullable<int>
bool hasValue = age.HasValue;
int value = age ?? 0;       // 默认值
int value2 = age.GetValueOrDefault(18);

5. 控制流

5.1 条件语句

// if-else
int score = 85;
if (score >= 90)
    Console.WriteLine("优秀");
else if (score >= 80)
    Console.WriteLine("良好");
else if (score >= 60)
    Console.WriteLine("及格");
else
    Console.WriteLine("不及格");

// switch 语句
var day = DayOfWeek.Monday;
switch (day)
{
    case DayOfWeek.Saturday:
    case DayOfWeek.Sunday:
        Console.WriteLine("周末");
        break;
    default:
        Console.WriteLine("工作日");
        break;
}

// switch 表达式(C# 8+)
string label = day switch
{
    DayOfWeek.Saturday or DayOfWeek.Sunday => "周末",
    _ => "工作日"
};

// 模式匹配 switch
object obj = 42;
string typeName = obj switch
{
    int => "整数",
    string => "字符串",
    double => "浮点数",
    null   => "null",
    _      => "其他"
};

5.2 循环语句

// for 循环
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}

// foreach 循环
var fruits = new[] { "苹果", "香蕉", "橙子" };
foreach (var fruit in fruits)
{
    Console.WriteLine(fruit);
}

// while 循环
int n = 10;
while (n > 0)
{
    Console.WriteLine(n--);
}

// do-while 循环
string? input;
do
{
    Console.Write("请输入 (q 退出): ");
    input = Console.ReadLine();
} while (input != "q");

// 范围与索引(C# 8+)
var numbers = new[] { 10, 20, 30, 40, 50 };
int last = numbers[^1];          // 50(最后一个元素)
int secondLast = numbers[^2];    // 40
var slice = numbers[1..4];       // [20, 30, 40]
var firstThree = numbers[..3];   // [10, 20, 30]

6. 模式匹配

C# 的模式匹配功能持续增强,是现代 C# 最重要的特性之一:

// is 模式
object value = 42;
if (value is int num and > 0 and < 100)
{
    Console.WriteLine($"0-100 之间的整数: {num}");
}

// 属性模式
public record Order(decimal Amount, string Status, Customer Customer);

string GetDiscount(Order order) => order switch
{
    { Status: "VIP", Amount: > 1000m } => "8折",
    { Status: "VIP" } => "9折",
    { Amount: > 500m } => "95折",
    _ => "无折扣"
};

// 列表模式(C# 11)
int[] numbers = [1, 2, 3];
string label = numbers switch
{
    [] => "空列表",
    [single] => $"单个元素: {single}",
    [first, .., last] => $"首: {first}, 尾: {last}",
    [var a, var b, ..] => $"前两个: {a}, {b}"
};

// when 守卫
string Classify(int[] arr) => arr switch
{
    [var a, .., var b] when a == b => "首尾相同",
    [var a, .., var b] when a < b => "递增趋势",
    _ => "其他"
};

7. 顶级语句与全局 Using

// GlobalUsings.cs - 全局 using 声明
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
global using System.IO;

// 隐式 using(csproj 中启用)
// <ImplicitUsings>enable</ImplicitUsings>
// 自动包含常用命名空间

// 文件范围命名空间(C# 10+)
namespace MyApp.Services;

public class UserService
{
    // 无需缩进,整个文件都在该命名空间下
}

// 顶级语句中的异步支持
var data = await FetchDataAsync();
Console.WriteLine($"获取到 {data.Length} 条记录");

async Task<string[]> FetchDataAsync()
{
    await Task.Delay(100);
    return ["item1", "item2", "item3"];
}

8. 运算符速查

// 空合并
string? name = null;
string result = name ?? "默认";       // 默认
name ??= "赋值";                      // null 时赋值

// 空条件
int? len = name?.Length;

// 类型模式
if (obj is string s) { /* 使用 s */ }
if (obj is not null) { /* 非 null */ }

// 范围运算符
var slice = array[1..^1]; // 跳过首尾

// with 表达式(record 类型)
var original = new Point(1, 2);
var modified = original with { X = 10 };

// 集合表达式(C# 12)
List<int> list = [1, 2, 3];
int[] arr = [..list, 4, 5]; // 展开 + 合并