C# 语句基础、核心概述及注释详解
C# 语言概述
C#(读作 "C Sharp")是微软于 2000 年推出的现代化编程语言,由 Anders Hejlsberg 主导设计。作为 .NET 生态系统的核心语言,C# 从诞生之初就确立了「类型安全、面向对象、组件导向」的设计目标。经过二十余年的持续演进,C# 已从最初的 Windows 专属语言发展为支持 Windows、Linux、macOS、Android、iOS 等全平台的通用编程语言。
在应用场景上,C# 覆盖了企业级应用开发的绝大多数领域:通过 ASP.NET Core 构建高性能 Web 服务与微服务;使用 WPF、WinUI 开发 Windows 桌面应用;借助 Unity 引擎进行游戏开发;利用 .NET MAUI 实现跨平台移动应用;在 ML.NET 与 TorchSharp 的支持下进入机器学习领域。这种「一门语言,多端覆盖」的能力,使 C# 成为企业技术栈中极具性价比的选择。
C# 的核心特性构成了其强大的工程化能力:强类型系统在编译期拦截类型错误;自动垃圾回收机制(GC)解放了内存管理负担;async/await 异步编程模型简化了高并发开发;LINQ 提供了声明式数据查询能力;泛型系统实现了类型安全的代码复用。这些特性相互配合,让 C# 在保持开发效率的同时,兼顾了运行性能与代码可维护性。
声明语句
声明语句用于向程序引入新的实体,包括变量、常量、类型(类、结构体、接口、枚举、委托等)。声明语句是程序结构的基石,决定了数据的存储方式与访问范围。
变量声明
变量是存储数据的命名容器,声明时必须指定类型(或使用 var 隐式类型),遵循「先声明后使用」的原则。
// 显式类型声明
int age = 25;
string name = "张三";
decimal salary = 8500.50m;
bool isActive = true;
// 隐式类型声明(var 由编译器推断类型,编译后仍是强类型)
var score = 95.5; // 推断为 double
var message = "Hello"; // 推断为 string
var items = new List<int>(); // 推断为 List<int>
// 可空值类型声明
int? nullableAge = null; // 表示可能为空的整数使用场景与限制:var 仅适用于局部变量,且必须在声明时初始化;类型推断结果在编译期确定,后续不能赋值为其他类型。
常量声明
常量是在编译期确定且不可修改的值,使用 const 关键字声明。常量隐式为静态成员,属于类型而非实例。
const double PI = 3.14159265359;
const string APP_NAME = "MyApplication";
const int MAX_RETRY_COUNT = 3;
// 常量必须在声明时初始化
// const int x; // 编译错误:常量必须初始化使用场景与限制:常量仅支持基元类型(数值、字符串、布尔)、枚举和引用类型(仅限 null 或字符串);运行时常量应使用 readonly 字段替代。
类型声明
C# 支持多种类型声明,用于构建程序的对象模型。
// 类声明(引用类型)
public class Person
{
public string Name { get; set; } = "未知";
public int Age { get; set; }
}
// 结构体声明(值类型)
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
// 接口声明
public interface IShape
{
double CalculateArea();
}
// 枚举声明
public enum Color { Red, Green, Blue }
// 记录声明(C# 9.0+,不可变引用类型)
public record Product(string Name, decimal Price);表达式语句
表达式语句由表达式加分号构成,执行计算或产生副作用(如赋值、方法调用)。表达式语句是程序逻辑的实际执行单元。
赋值表达式
赋值是最基本的副作用操作,将右侧表达式的值赋予左侧变量。
int x = 10;
x = 20; // 简单赋值
x += 5; // 复合赋值,等价于 x = x + 5
x *= 2; // 复合赋值,等价于 x = x * 2
// 元组赋值与解构
(string name, int age) = ("李四", 30);
var (n, a) = ("王五", 28);算术运算表达式
C# 支持标准的算术运算符,遵循数学运算优先级。
int a = 10, b = 3;
int sum = a + b; // 加法,结果 13
int diff = a - b; // 减法,结果 7
int product = a * b; // 乘法,结果 30
int quotient = a / b; // 整数除法,结果 3(截断小数)
int remainder = a % b; // 取余,结果 1
double precise = 10.0 / 3.0; // 浮点除法,结果 3.333...
// checked/unchecked 控制溢出检查
int max = int.MaxValue;
// int overflow = max + 1; // 默认不检查,结果溢出
int @checked = checked(max + 1); // 抛出 OverflowException方法调用表达式
方法调用是程序复用逻辑的基本方式,通过参数传递数据,通过返回值获取结果。
// 实例方法调用
string text = "Hello, C#";
int length = text.Length; // 属性访问(特殊的方法调用)
string upper = text.ToUpper(); // 无参方法
string sub = text.Substring(0, 5); // 带参方法,结果 "Hello"
// 静态方法调用
int max = Math.Max(10, 20);
bool isNumber = int.TryParse("123", out int result);
// 扩展方法调用(LINQ)
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evens = numbers.Where(n => n % 2 == 0).ToList();对象创建表达式
使用 new 运算符创建类型实例,分配内存并调用构造函数。
// 类实例创建
Person person = new Person { Name = "赵六", Age = 35 };
// 集合初始化
var list = new List<int> { 1, 2, 3, 4, 5 };
var dict = new Dictionary<string, int> { ["one"] = 1, ["two"] = 2 };
// 数组创建
int[] array = new int[5]; // 声明长度为 5 的数组
int[] init = new int[] { 1, 2, 3 }; // 声明并初始化
int[] shorthand = { 1, 2, 3 }; // 简写形式C# 注释体系
注释是写给开发者阅读的代码说明,编译器在编译时会完全忽略注释内容。良好的注释习惯是专业开发者的基本素养,C# 提供了四类注释满足不同场景的文档需求。
单行注释 //
单行注释用于解释单行代码的意图或临时禁用代码,注释范围从 // 到行尾。
int age = 25; // 用户年龄,用于后续业务判断
// 以下代码暂时禁用,待需求确认后恢复
// Console.WriteLine("调试信息");最佳实践:单行注释应解释「为什么」而非「是什么」;避免无意义的注释如 int x = 10; // 设置x为10。
多行注释 /* */
多行注释用于大段说明、文件头版权信息或临时注释掉代码块。
/*
* 文件:Program.cs
* 作者:开发团队
* 日期:2025-01-15
* 描述:应用程序入口点
*/
/*
int oldValue = CalculateOld();
ProcessLegacy(oldValue);
*/重要限制:多行注释不能嵌套。以下代码会产生编译错误:
/*
外层注释
/* 内层注释 */ // 错误:第一个 */ 会提前结束外层注释
*/若需注释掉包含多行注释的代码块,应使用 #if 预处理指令:
#if false
/*
这段代码被整体禁用
/* 内部的多行注释不会导致问题 */
*/
#endifXML 文档注释 ///
XML 文档注释是 C# 的专属特性,用于生成结构化的 API 文档。注释内容会被编译器提取并生成 XML 文件,供 IDE 智能感知和文档工具使用。
/// <summary>
/// 计算两个整数的和
/// </summary>
/// <param name="a">第一个加数</param>
/// <param name="b">第二个加数</param>
/// <returns>两数之和</returns>
/// <exception cref="OverflowException">当结果超出 int 范围时抛出</exception>
/// <example>
/// <code>
/// int result = MathHelper.Add(3, 5);
/// Console.WriteLine(result); // 输出: 8
/// </code>
/// </example>
public static int Add(int a, int b)
{
return checked(a + b);
}常用标签说明:
| 标签 | 用途 | 适用位置 |
|---|---|---|
<summary> | 类型或成员的简要说明 | 类、方法、属性等 |
<param> | 方法参数说明 | 方法 |
<returns> | 返回值说明 | 方法、属性 |
<exception> | 可能抛出的异常 | 方法 |
<example> | 使用示例 | 任何成员 |
<code> | 示例代码块 | <example> 内 |
<remarks> | 补充说明 | 任何成员 |
<see> / <seealso> | 交叉引用 | 任何成员 |
<value> | 属性值说明 | 属性 |
<typeparam> | 泛型参数说明 | 泛型类型/方法 |
生成帮助文档的操作流程:
- 启用 XML 文档生成:在项目文件(.csproj)中添加:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- 可选:忽略缺失注释的警告 -->
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>编译项目:
dotnet build会在输出目录生成与程序集同名的 XML 文件。生成可视化文档:使用第三方工具将 XML 转换为 HTML/PDF:
- DocFX:微软官方推荐的文档生成工具,支持 Markdown 扩展
- Sandcastle:经典的帮助文件生成器,可输出 CHM 格式
- Doxygen:跨语言文档工具,支持多种输出格式
# DocFX 快速开始
dotnet tool install -g docfx
docfx init -q
docfx docfx.json --serve区域注释 #region / #endregion
区域注释用于在 IDE 中创建可折叠的代码块,帮助组织大型文件的结构。区域注释不影响编译,纯粹是代码组织工具。
public class OrderService
{
#region 字段与属性
private readonly IRepository _repository;
public string ServiceName { get; } = "订单服务";
#endregion
#region 构造函数
public OrderService(IRepository repository)
{
_repository = repository;
}
#endregion
#region 公共方法
public void CreateOrder() { /* ... */ }
public void CancelOrder() { /* ... */ }
#endregion
#region 私有辅助方法
private void Validate() { /* ... */ }
private void Log() { /* ... */ }
#endregion
}最佳实践:区域注释应反映逻辑结构而非机械地按访问修饰符分组;避免嵌套过深(建议不超过两层);现代 IDE 的「大纲视图」已能替代部分区域注释功能,应适度使用。
易错点提示
switch 语句的穿透规则
C# 的 switch 语句不支持隐式穿透,每个 case 分支必须以 break、return、throw 或 goto 结束,否则编译报错。
// 错误:缺少 break,编译失败
switch (value)
{
case 1:
Console.WriteLine("一");
case 2: // 错误:控制不能从一个 case 标签贯穿到另一个 case 标签
Console.WriteLine("二");
break;
}
// 正确:显式使用 goto case 实现可控穿透
switch (value)
{
case 1:
Console.Write("一");
goto case 2; // 显式跳转到 case 2
case 2:
Console.WriteLine("(或二)");
break;
}XML 注释的编译要求
XML 文档注释仅在启用 GenerateDocumentationFile 时才会被编译器提取;若未启用,注释仍存在于源代码中,但不会影响编译结果。缺失 XML 注释会产生编译警告(CS1591),可通过 <NoWarn> 抑制。
多行注释的嵌套限制
多行注释 /* */ 不能嵌套,第一个 */ 会结束最外层的注释。需要注释掉包含多行注释的代码块时,必须使用 #if false 预处理指令或逐行使用单行注释。
注释维护的陷阱
注释与代码不同步是技术债务的常见来源。修改代码时务必同步更新相关注释;避免在注释中记录可通过版本控制追溯的信息(如修改日期、作者);复杂的业务逻辑应通过重构使代码自解释,而非依赖大段注释。
知识要点回顾
| 模块 | 核心内容 | 关键要点 |
|---|---|---|
| C# 概述 | 语言定位、应用场景、核心特性 | 类型安全、面向对象、.NET 生态核心 |
| 声明语句 | 变量、常量、类型声明 | var 仅局部变量、const 编译期确定 |
| 表达式语句 | 赋值、算术运算、方法调用、对象创建 | 副作用操作、整数除法截断 |
| 单行注释 | // 语法 | 解释「为什么」而非「是什么」 |
| 多行注释 | /* */ 语法 | 不可嵌套、大段代码禁用用 #if |
| XML 文档注释 | /// 标签体系 | <summary>、<param>、<returns>、<exception> |
| 区域注释 | #region / #endregion | 逻辑分组、适度使用、避免嵌套过深 |
| 易错点 | switch 穿透、XML 编译要求、注释嵌套 | C# 禁止隐式穿透、XML 需启用生成 |