C# 基础认知
变量与数据类型
控制流(分支与循环)
数组(Array)
集合(Collection)
可空引用类型
using System; // 引入命名空间
class Program
{
static void Main(string[] args) // 程序入口
{
Console.WriteLine("Hello, C#!"); // 输出并换行
Console.Write("不换行"); // 输出不换行
Console.ReadKey(); // 等待按键
}
}写法 | 说明 | 适用版本 |
|---|---|---|
| 传统手动引入 | 所有版本 |
隐式全局 using | 项目文件启用 | .NET 6+ |
| 引入静态成员,可省略类名 | C# 6+ |
| 起别名 | 所有版本 |
// 隐式 using 自动引入的命名空间(.NET 6+ 控制台模板)
// System, System.Collections.Generic, System.Linq, System.Text, System.Threading.Tasks类型 | 关键字 | 字节 | 范围 | 示例 |
|---|---|---|---|---|
有符号8位 | sbyte | 1 | -128 ~ 127 |
|
无符号8位 | byte | 1 | 0 ~ 255 |
|
有符号16位 | short | 2 | -32,768 ~ 32,767 |
|
无符号16位 | ushort | 2 | 0 ~ 65,535 |
|
有符号32位 | int | 4 | -21亿 ~ 21亿 |
|
无符号32位 | uint | 4 | 0 ~ 42亿 |
|
有符号64位 | long | 8 | -922亿亿 ~ 922亿亿 |
|
无符号64位 | ulong | 8 | 0 ~ 1844亿亿 |
|
单精度 | float | 4 | ±3.4×10³⁸(7位精度) |
|
双精度 | double | 8 | ±1.7×10³⁰⁸(15位精度) |
|
高精度 | decimal | 16 | ±7.9×10²⁸(28位精度) |
|
布尔值 | bool | 1 | true/false |
|
字符 | char | 2 | Unicode字符 |
|
类型 | 关键字 | 示例 |
|---|---|---|
字符串 | string |
|
数组 | int[] |
|
对象 | object |
|
引号类型 | 用于 | 示例 | 说明 |
|---|---|---|---|
双引号 | string |
| 零个或多个字符 |
单引号 | char |
| 必须且只能一个字符 |
// 方式1:显式声明(最常用)
int age = 25;
string name = "张三";
// 方式2:先声明后赋值
double height;
height = 175.5;
// 方式3:隐式类型(var)
var city = "北京"; // 推断为 string
var score = 95; // 推断为 int
// ⚠️ var 不能用于:未初始化、null、类字段
// 方式4:常量
const double PI = 3.14159;
// 方式5:同时声明多个
int x = 1, y = 2, z = 3;// 隐式转换(自动,安全)
int small = 100;
long big = small; // int → long
double d = small; // int → double
// 显式转换(强制,可能丢失)
double pi = 3.99;
int integer = (int)pi; // 结果为 3(截断,不是四舍五入)
// 安全转换方法
string text = "123";
int number = Convert.ToInt32(text);
int number2 = int.Parse(text); // 可能抛异常
bool success = int.TryParse(text, out int result); // 安全,不抛异常
// 数字转字符串
string str = number.ToString();
string str2 = $"{number}";double value = 1234.5678;
// 标准格式(不区分大小写)
Console.WriteLine($"{value:f2}"); // 1234.57(2位小数)
Console.WriteLine($"{value:F4}"); // 1234.5678(4位小数)
Console.WriteLine($"{value:n2}"); // 1,234.57(千位分隔符)
Console.WriteLine($"{value:p1}"); // 123456.8%(百分比)
Console.WriteLine($"{value:e2}"); // 1.23e+003(科学计数法)
Console.WriteLine($"{value:c}"); // $1,234.57(货币,取决于区域)
// 十六进制(区分大小写)
int hex = 255;
Console.WriteLine($"{hex:x}"); // ff(小写)
Console.WriteLine($"{hex:X}"); // FF(大写)需要存储什么数据?
│
├─ 整数
│ ├─ < 255 → byte
│ ├─ < 32,767 → short
│ ├─ < 21亿 → int ✅
│ ├─ > 21亿 → long
│ └─ 只知道正数 → 考虑无符号(uint/ulong)
│
├─ 小数
│ ├─ 财务/货币 → decimal ✅
│ ├─ 科学/工程 → double ✅
│ └─ 游戏/图形/3D → float
│
└─ 未知/混合 → double// 基本语法
if (条件1)
{
// 条件1为true时执行
}
else if (条件2)
{
// 条件1为false,条件2为true时执行
}
else
{
// 所有条件都为false时执行
}
// 示例
int score = 85;
if (score >= 90)
Console.WriteLine("优秀"); // 单条语句可省略{},但不推荐
else if (score >= 80)
Console.WriteLine("良好");
else
Console.WriteLine("继续加油");// 传统 switch(C# 1.0)
string day = "周三";
switch (day)
{
case "周一":
Console.WriteLine("开始新的一周");
break; // 必须 break
case "周三":
Console.WriteLine("一周过半");
break;
case "周五":
Console.WriteLine("周末快到了");
break;
default:
Console.WriteLine("普通的一天");
break;
}
// switch 表达式(C# 8.0+)
string result = day switch
{
"周一" => "开始新的一周",
"周三" => "一周过半",
"周五" => "周末快到了",
_ => "普通的一天" // _ 相当于 default
};
Console.WriteLine(result);
// 模式匹配(C# 8.0+)
object obj = 42;
string type = obj switch
{
int i when i > 0 => "正整数",
int i when i < 0 => "负整数",
string s => $"字符串:{s}",
null => "空值",
_ => "其他类型"
};// 简单 if-else 的简写
int age = 18;
string status = (age >= 18) ? "成年人" : "未成年人";
// 嵌套三元(不推荐,可读性差)
string level = score >= 90 ? "A" : score >= 80 ? "B" : "C";// 基本语法
for (初始化; 条件; 迭代)
{
// 循环体
}
// 示例:输出 1 到 5
for (int i = 1; i <= 5; i++)
{
Console.WriteLine($"第 {i} 次循环");
}
// 多个变量
for (int i = 0, j = 10; i < j; i++, j--)
{
Console.WriteLine($"i={i}, j={j}");
}
// 死循环
for (;;)
{
// 需要 break 退出
}// while(先判断后执行)
int count = 0;
while (count < 5)
{
Console.WriteLine($"计数: {count}");
count++;
}
// do-while(至少执行一次)
int number;
do
{
Console.Write("请输入正数:");
} while (!int.TryParse(Console.ReadLine(), out number) || number <= 0);
Console.WriteLine($"你输入了 {number}");// 遍历集合(最安全,只读)
string[] names = { "张三", "李四", "王五" };
foreach (string name in names)
{
Console.WriteLine($"你好,{name}!");
}
// 获取索引(需要额外变量)
int index = 0;
foreach (var item in collection)
{
Console.WriteLine($"[{index}] = {item}");
index++;
}// break:跳出循环
for (int i = 1; i <= 10; i++)
{
if (i == 5) break;
Console.Write(i + " "); // 1 2 3 4
}
// continue:跳过本次循环
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0) continue;
Console.Write(i + " "); // 1 3 5 7 9
}
// return:退出方法
static void Test()
{
for (int i = 1; i <= 10; i++)
{
if (i == 5) return; // 直接结束方法
Console.Write(i + " "); // 1 2 3 4
}
Console.WriteLine("不会执行");
}
// goto:跳转到标签(不推荐使用)
for (int i = 0; i < 10; i++)
{
if (i == 5) goto End;
}
End:
Console.WriteLine("结束");循环类型 | 适用场景 | 是否知道次数 |
|---|---|---|
for | 已知循环次数 | ✅ 知道 |
while | 条件控制,可能一次都不执行 | ❌ 不知道 |
do-while | 条件控制,至少执行一次 | ❌ 不知道 |
foreach | 遍历集合/数组 | ✅ 知道(由集合决定) |
// 方式1:最传统(C# 1.0)
string[] names1 = new string[3];
names1[0] = "张三";
names1[1] = "李四";
names1[2] = "王五";
// 方式2:声明时分配(指定大小)
string[] names2 = new string[3] { "张三", "李四", "王五" };
// 方式3:省略大小(编译器推断)
string[] names3 = new string[] { "张三", "李四", "王五" };
// 方式4:数组初始化器(C# 3.0+)
string[] names4 = { "张三", "李四", "王五" }; // ⭐ 最常见
// 方式5:集合表达式(C# 12.0+ / .NET 8+)
string[] names5 = ["张三", "李四", "王五"]; // ⭐ 最新写法
// 空数组
string[] empty1 = new string[0];
string[] empty2 = Array.Empty<string>();
string[] empty3 = { };
string[] empty4 = []; // C# 12+ 最简洁// 矩形数组(二维)
int[,] matrix = new int[3, 4]; // 3行4列
int[,] matrix2 = { {1, 2}, {3, 4}, {5, 6} };
Console.WriteLine(matrix2[0, 1]); // 2
// 锯齿数组(数组的数组)
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 };
jagged[1] = new int[] { 3, 4, 5 };
jagged[2] = new int[] { 6 };
Console.WriteLine(jagged[1][2]); // 5int[] arr = { 5, 2, 8, 1, 9 };
// 长度
int len = arr.Length;
// 排序
Array.Sort(arr); // { 1, 2, 5, 8, 9 }
// 反转
Array.Reverse(arr); // { 9, 8, 5, 2, 1 }
// 查找
int index = Array.IndexOf(arr, 5); // 2
int index2 = Array.LastIndexOf(arr, 5);
// 复制
int[] copy = new int[3];
Array.Copy(arr, copy, 3);
// 清空
Array.Clear(arr, 0, arr.Length); // 全部设为默认值(0/null)特性 | 数组 |
|
|---|---|---|
大小 | 固定,不可变 | 动态,自动扩容 |
性能 | 更快 | 稍慢(有额外开销) |
添加元素 | 不支持 |
|
删除元素 | 不支持 |
|
使用场景 | 固定数据 | 频繁增删改查 |
using System.Collections.Generic;
// 创建方式
List<string> names = new List<string>();
List<int> scores = new List<int> { 90, 85, 78, 92 }; // 初始化
var list = new List<string>(); // var 推断
List<string> list2 = []; // C# 12+ 集合表达式
// 常用操作
names.Add("张三"); // 添加
names.Insert(1, "赵六"); // 插入
names.Remove("李四"); // 删除
names.RemoveAt(0); // 按索引删除
names.RemoveAll(x => x.StartsWith("张")); // 条件删除
int count = names.Count; // 个数
bool exists = names.Contains("王五"); // 是否存在
int idx = names.IndexOf("李四"); // 查找索引(-1表示不存在)
names.Sort(); // 排序
names.Reverse(); // 反转
names.Clear(); // 清空
// 批量操作
names.AddRange(new[] { "赵六", "孙七" }); // 批量添加
List<string> subList = names.GetRange(0, 2); // 获取子列表// 创建方式
Dictionary<int, string> students = new Dictionary<int, string>();
Dictionary<string, int> scores = new()
{
{ "张三", 95 },
{ "李四", 87 }
};
var dict = new Dictionary<string, string>();
// 常用操作
students.Add(1001, "张三"); // 添加
students[1002] = "李四"; // 添加或覆盖
string name = students[1001]; // 访问(可能抛异常)
// 安全访问
if (students.ContainsKey(1003))
{
Console.WriteLine(students[1003]);
}
// TryGetValue(最佳实践)
if (students.TryGetValue(1004, out string? foundName))
{
Console.WriteLine($"找到:{foundName}");
}
else
{
Console.WriteLine("学号不存在");
}
// 遍历
foreach (KeyValuePair<int, string> kvp in students)
{
Console.WriteLine($"键:{kvp.Key},值:{kvp.Value}");
}
// 只遍历键或值
foreach (int id in students.Keys) { }
foreach (string studentName in students.Values) { }
// 删除
students.Remove(1001);
students.Clear();HashSet<string> uniqueNames = new HashSet<string>();
uniqueNames.Add("张三");
uniqueNames.Add("李四");
bool added = uniqueNames.Add("张三"); // false(已存在)
// 初始化
HashSet<int> set = new HashSet<int> { 1, 2, 3, 4, 5 };
// 集合操作
HashSet<int> set1 = new HashSet<int> { 1, 2, 3 };
HashSet<int> set2 = new HashSet<int> { 3, 4, 5 };
set1.IntersectWith(set2); // 交集:{3}
set1.UnionWith(set2); // 并集:{1,2,3,4,5}
set1.ExceptWith(set2); // 差集:{1,2}
set1.SymmetricExceptWith(set2); // 对称差:{1,2,4,5}
bool isSuperset = set1.IsSupersetOf(set2);
bool isSubset = set1.IsSubsetOf(set2);Stack<string> stack = new Stack<string>();
stack.Push("操作1"); // 压入
stack.Push("操作2");
stack.Push("操作3");
string last = stack.Pop(); // "操作3"(弹出)
string top = stack.Peek(); // "操作2"(只看不弹)
bool isEmpty = stack.Count == 0;Queue<string> queue = new Queue<string>();
queue.Enqueue("任务1"); // 入队
queue.Enqueue("任务2");
queue.Enqueue("任务3");
string first = queue.Dequeue(); // "任务1"(出队)
string next = queue.Peek(); // "任务2"(只看不出)集合 | 特点 | 有序 | 重复 | 访问方式 | 适用场景 |
|---|---|---|---|---|---|
| 动态数组 | ✅ | ✅ | 索引 | 存储列表数据 |
| 键值对 | ❌ | 键唯一 | 键 | 通过ID快速查找 |
| 唯一值 | ❌ | ❌ |
| 去重、集合运算 |
| 后进先出 | ✅ | ✅ |
| 撤销、递归 |
| 先进先出 | ✅ | ✅ |
| 任务队列 |
C# 8.0+ 引入,引用类型分为两种:
类型 | 声明 | 能否为null | 说明 |
|---|---|---|---|
不可为空 |
| ❌ | 保证永远有值 |
可为空 |
| ✅ | 可能为null,需要检查 |
// 1. 声明为可空类型
if (dict.TryGetValue(1004, out string? value))
{
Console.WriteLine(value);
}
// 2. var 自动推断为可空
if (dict.TryGetValue(1004, out var value))
{
Console.WriteLine(value);
}
// 3. 空值合并运算符 ??
string name = GetName() ?? "默认用户";
// 4. 空值合并赋值 ??=
string? input = null;
input ??= "默认值"; // input 现在为 "默认值"
// 5. 空值条件运算符 ?.
string? user = null;
int length = user?.Length ?? 0; // 避免 NullReferenceException
// 6. 空值条件 + 索引
string? first = users?.FirstOrDefault()?.Name;
// 7. 非空断言运算符 !(告诉编译器"我保证不为null",谨慎使用)
string name = GetName()!;// 值类型默认不可为null
int x = null; // ❌ 编译错误
// 使用 Nullable<T> 或 T? 使其可为null
int? y = null; // ✅ 可为null
bool? flag = null; // ✅ 可为null
// 访问可空值类型
int? age = null;
if (age.HasValue)
{
Console.WriteLine(age.Value);
}
else
{
Console.WriteLine("年龄未知");
}
// 使用 GetValueOrDefault
int actualAge = age.GetValueOrDefault(); // 如果为null,返回默认值0
int actualAge2 = age ?? 18; // 如果为null,使用18<!-- .csproj 文件中 -->
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <!-- 开启可空检查 -->
</PropertyGroup>// 数组初始化
int[] arr = { 1, 2, 3 }; // 传统
int[] arr = [1, 2, 3]; // C# 12+
// List 初始化
List<int> list = new List<int> { 1, 2, 3 };
List<int> list = [1, 2, 3]; // C# 12+
// Dictionary 初始化
var dict = new Dictionary<string, int>
{
{ "a", 1 },
{ "b", 2 }
};
// C# 12+ 暂不支持字典集合表达式
// 空集合
int[] empty = []; // 数组空
List<int> empty = []; // List空
string[] empty = Array.Empty<string>(); // 无分配空数组if (条件) { } else if { } else { }
switch (值) { case 常量: break; default: break; }
条件 ? 真值 : 假值
for (初始化; 条件; 迭代) { }
while (条件) { }
do { } while (条件)
foreach (var item in 集合) { }
break / continue / return