C# 常见语法糖详解与代码示例

闻溪
闻溪
发布时间:2026-10-16 | 5人浏览过
原创

本文详细解析 C# 语言中的各类语法糖特性,涵盖自动属性、Lambda 委托、集合初始化、隐式类型声明 var、空值处理运算符、对象初始化器、扩展方法及匿名类。通过具体代码示例,对比新旧写法差异,帮助开发者理解编译器背后的逻辑,从而写出更简洁、易读的 C# 代码。

结果或目标

C# 的“语法糖”是指那些不会改变程序行为,但能简化代码书写、提高可读性的语言特性。合理使用这些特性可以显著减少样板代码(Boilerplate Code),让核心逻辑更突出。以下将逐一介绍在实际开发中最常用且最具代表性的语法糖。

准备条件

  1. 具备 C# 基础语法知识。
  2. 使用支持 C# 3.0 及以上版本的开发环境(如 Visual Studio, .NET Core/.NET 5+)。
  3. 了解基本的面向对象概念及 LINQ 初步概念(针对部分高级特性)。

真实操作顺序

第1步:使用自动属性简化 Property 定义

目的:减少手动创建私有字段和 Getter/Setter 的代码量。

背景:在早期版本中,每个属性都需要显式定义 backing field(后备字段)。

动作:直接使用 { get; set; } 省略体属性。

复制代码 代码如下:
// 旧写法
private string _myName;
public string MyName {
    get { return _myName; }
    set { _myName = value; }
}

// 新写法(自动属性)
public string MyName { get; set; }

重要参数/细节:依然可以单独设置访问修饰符,例如 { get; private set; } 实现外部只读。

第2步:利用 Lambda 表达式简化委托

目的:避免冗长的委托声明和方法引用,支持闭包捕获局部变量。

入口:任何需要 Delegate 或 Action/Func 参数的场景。

动作:使用 => 箭头符号。

复制代码 代码如下:
class MyClass {
    public delegate void DoSomething(int a);
    
    // 定义一个内部变量用于演示闭包
    private int x = 10;

    public void Process(DoSomething doMethod, int val) {
        doMethod(val);
    }

    public static void Main() {
        MyClass mc = new MyClass();
        
        // 1. 传统方法引用
        mc.Process(mc.DoIt, 10);
        
        // 2. 匿名委托
        mc.Process(delegate(int a) { Console.WriteLine(a + mc.x); }, 10);
        
        // 3. Lambda 表达式(最简形式)
        mc.Process(a => Console.WriteLine(a + mc.x), 10);
    }

    private void DoIt(int a) {
        Console.WriteLine(a);
    }
}

第3步:使用集合初始化和 ForEach 简化列表操作

目的:在声明时直接赋值元素,并简化遍历逻辑。

动作:使用大括号 {} 进行初始化;使用 List.ForEach() 替代 foreach 循环(适用于简单单行操作)。

复制代码 代码如下:
// 集合初始化
List<string> list = new List<string> { "def", "OK" };

// 替代 foreach 的单步操作
list.ForEach(a => Console.WriteLine(a));

第4步:用 using 语句管理资源释放

目的:确保实现了 IDisposable 的对象在使用后能被正确清理,防止资源泄漏。

风险提醒:如果在 using 块内抛出异常,Dispose() 仍会被调用。确保对象构造函数成功执行后再进入 using,否则可能触发 NullReferenceException。

动作:将资源创建和用法包裹在 using 块中。

复制代码 代码如下:
// 等价于 try...finally { Dispose() }
using (var sw = new StreamWriter("d:\\abc.txt")) {
    sw.WriteLine("test");
}

第5步:启用隐式类型 var

目的:减少类型重复输入,提高编码速度,但不影响编译期类型检查。

限制:仅适用于局部变量;必须在声明时初始化;类型一旦确定不可更改。

动作:使用 var 关键字代替显式类型。

复制代码 代码如下:
var writer = new StreamWriter(path);
for (var i = 0; i < 100; i++) { }

第6步:利用问号简化条件判断

目的:快速处理三元条件逻辑和空值默认值。

动作:使用 ?: 进行三元运算,使用 ?? 处理 null 值回退。

复制代码 代码如下:
int b = 3;
// 三元运算符:如果 b > 9 则转字符串,否则补零
var a = b > 9 ? b.ToString() : "0" + b;

string s = null;
// 空合并运算符:如果 s 为 null 则返回 "",否则返回 s
var result = s ?? "";

第7步:对象初始化器无需构造函数

目的:在不自定义构造函数的情况下,直观地设置对象属性。

动作:在大括号内直接赋值属性名和值。

复制代码 代码如下:
public class Abc {
    public int ID { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
}

// 实例化并赋值
var abc = new Abc {
    ID = 1,
    Name = "jb51",
    Url = "http://jb51.jb51.net/"
};

第8步:引入扩展方法增强现有类型

目的:为非密封类(如 String)添加实用方法,而无需修改源码或继承子类。

入口:创建一个静态类,其中包含带有 this 关键字参数的静态方法。

动作:定义扩展方法并调用。

复制代码 代码如下:
using System.Text.RegularExpressions;

public static class StringExt {
    static private Regex regexNumber = new Regex(@"\d+");
    
    // 注意 this string input 关键字
    static public bool IsNumber(this string input) {
        if (string.IsNullOrEmpty(input)) return false;
        return regexNumber.IsMatch(input);
    }
}

// 调用
var text = "123";
bool isNum = text.IsNumber(); // 像普通方法一样调用

第9步:使用匿名类型进行临时数据封装

目的:在 LINQ 查询或需要轻量级 DTO 的场景下,无需提前定义类结构。

动作:使用 new { ... } 直接实例化。

复制代码 代码如下:
// 编译器自动生成类型,不可用于方法返回值或字段
var userInfo = new {
    ID = 1,
    Name = "jb51",
    BlogUrl = "https://www.jb51.net"
};

完成判断

当代码不再包含冗余的 Setter/Getter 手写实现、委托调用更加简洁、变量声明清晰且资源释放自动化时,即表明已成功运用上述 C# 语法糖优化了代码结构。

原文有依据的排错

  • var 的使用范围: 原文提到 var 只能作为局部变量,这是正确的。它不能用于类字段、方法参数或返回值类型。
  • 扩展方法的静态性: 必须确保定义扩展方法的容器类是 static 的,方法本身也是 static 的,否则编译报错。

简要总结

以上就是 C# 常用语法糖(包括自动属性、Lambda、var、扩展方法等)的详细内容,更多关于 C# 编程技巧与最佳实践的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表