告别过时写法!5个现代C#技巧让你的代码更简洁、更安全

作者:微信公众号:【架构师老卢】
9-23 14:6
157

C#已经存在了二十多年,每个新版本都会悄悄加入一些特性,让日常编码更简洁、更安全、更优雅。问题是大多数开发者还停留在五年前学到的编码方式中。

他们还在不停地输入 using (...) {},用命名空间的大括号堆砌文件,或者忘记空安全性和必需属性存在的意义。

本文讨论了5个现代C#技巧,可以减少代码冗余,让你的意图更加清晰。这些技巧并不复杂,也不小众,而是那种能够逐渐累积形成更清晰、更易维护代码的习惯。

1. 在is模式中使用解构 C#中的模式匹配已经发展成为该语言最具表现力的特性之一。一个很好的例子就是在is模式中使用解构。你无需先检查类型再赋值,而是可以在单个语句中获取所有需要的信息。

旧写法:

if (person is Employee e)
{
    var id = e.Id;
    var department = e.Department;
    Console.WriteLine($"{id} - {department}");
}

这样写虽然可行,但感觉有些冗余。

更好的写法:

if (person is Employee(var id, var department))
{
    Console.WriteLine($"{id} - {department}");
}

只要你的类型有解构器(比如记录类型就有),这种方法就能减少重复,让条件判断一目了然。你无需分两步操作,直接在if语句中声明你的意图。

2. 使用文件作用域命名空间简化代码文件 多年来,每个C#文件都以namespace MyApp { ... }开头,这迫使你进入不必要的缩进层级。一旦你的类变得庞大,屏幕的一半空间都会被用来维护大括号。

旧风格:

namespace MyApp.Core
{
    public class UserService
    {
        // 所有内容都需要缩进
    }
}

文件作用域命名空间风格:

namespace MyApp.Core;

public class UserService
{
    // 简洁平整
}

这可能看起来是小事,但一旦你在整个代码库中应用它,每个文件都会立刻感觉更轻量。减少一层视觉噪音让你更容易专注于重要的事情:你的实际代码。

3. 在对象初始化器中优先使用必需属性以确保安全 你见过多少次User对象在你的系统中游荡,却缺少电子邮件、ID或其他绝对不应为空的属性?这正是required关键字大放异彩的地方。

没有required的情况:

public class User
{
    public string Name { get; set; }
    public string Email { get; set; }
}

// 这能编译但是不完整
var user = new User { Name = "Alice" };

这能编译通过,但现在你有一个缺少电子邮件的User对象。这是一个潜在的bug。

使用required的情况:

public class User
{
    public required string Name { get; init; }
    public required string Email { get; init; }
}

var user = new User { Name = "Alice", Email = "alice@mail.com" };

编译器会强制要求设置Name和Email属性。没有捷径可走,不会忘记赋值。这就像在你的类型系统中内置了一个安全网,对于领域驱动设计特别有益,因为不完整的对象可能会破坏业务规则。

4. 使用声明式using var替代嵌套块 旧的using语句迫使你使用块作用域,这很快会变成令人畏惧的"金字塔厄运"。

旧风格:

using (var stream = new FileStream("file.txt", FileMode.Open))
{
    using (var reader = new StreamReader(stream))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}

现代风格:

using var stream = new FileStream("file.txt", FileMode.Open);
using var reader = new StreamReader(stream);
Console.WriteLine(reader.ReadToEnd());

资源仍然会自动释放,但你避免了混乱的嵌套。代码保持线性,这意味着更易于阅读和调试。

5. 在switch表达式中优先使用弃元_避免冗余的default Switch表达式让条件逻辑简洁明了,但许多开发者仍然用不必要的default关键字来堆砌它们。

冗长写法:

var result = status switch
{
    200 => "OK",
    404 => "Not Found",
    default => "Unknown"
};

使用弃元更简洁:

var result = status switch
{
    200 => "OK",
    404 => "Not Found",
    _ => "Unknown"
};

使用_清楚地表明你在处理"其他所有情况"。这不是你忘记考虑的兜底方案,而是一个有意识的回退处理。


你编写C#的时间越长,就越会意识到是那些小习惯造成了最大的不同。用文件作用域命名空间减少多余的大括号,用必需属性强制创建有效对象,或者用using var扁平化代码——这些可能看起来不炫酷,但随着时间的推移,它们会累积成更容易信任、更容易阅读的代码。

关键在于保持对语言发展的关注。这些特性大多已经存在多年,但许多代码库仍然停留在2010年代的模式中。你越早开始采用这些现代实践,你的代码库就能越早停止与你对抗,开始与你协作。

相关留言评论
昵称:
邮箱:
阅读排行