25个C#最佳实践:从菜鸟到高手,写出整洁高效的优质代码

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

编写整洁、高效且可维护的C#代码是高级开发者的标志。初级开发者通常只关注让代码运行起来,而有经验的程序员则强调可读性、性能和可维护性。

在本指南中,我将分享25个必备的C#最佳实践,这些实践将帮助您编写更好的代码——无论您是希望提升技能的初学者,还是想要精进技艺的经验丰富的开发者。

1. 对于数据转换,使用 Select 而非 ForEach 为何? ForEach 适用于迭代,但在其中修改集合可能导致意外的副作用。

更好的方法(使用 Select)

var names = users.Select(u => u.Name);

示例用例: 如果您需要从用户集合中获取姓名列表,Select 提供了一种更清晰、更函数式的方法。

2. 使用 LINQ 编写更简洁的查询 LINQ 简化了过滤和转换操作,使代码更具可读性。

示例:

var adults = users.Where(u => u.Age >= 18);

与编写 foreach 循环相比,LINQ 使查询简洁且富有表现力。

3. 封装业务逻辑 将逻辑保持在相关的类中,可确保功能是模块化且可重用的。

示例:

class Order 
{ 
    bool IsValid() => totalPrice > 0; 
}

这里,IsValid 被封装在 Order 类中,使其可以在应用程序中重用。

4. 对简单条件使用三元运算符 三元运算符有助于保持条件判断的简洁性。

示例:

string status = age >= 18 ? "Adult" : "Minor";

这避免了为小的条件检查编写不必要的 if-else 语句。

5. 对简单数据结构使用元组 无需定义不必要的类结构时,可使用元组进行轻量级数据存储。

示例:

var person = (Name: "John", Age: 30);
Console.WriteLine(person.Name);

这在您不需要完整类的情况下非常有用。

6. 使用 is not null 代替 != null 在检查 null 时提高了可读性。

示例:

if (users is not null) { ... }

这遵循了现代 C# 语法的最佳实践。

7. 使用 Any() 代替 Count() > 0 使用 Count() 检查集合中是否存在元素是低效的。

更好的方法:

if (users.Any()) { ... }

Any() 在找到第一个元素时就会短路返回,而不像 Count() 需要遍历所有元素。

8. 使用 FirstOrDefault 代替 First 不检查元素是否存在就使用 First() 可能会抛出异常。

更好的方法:

var user = users.FirstOrDefault(u => u.Id == id);

如果集合为空,这可以防止运行时错误。

9. 避免不必要的使用 ToList() ToList() 会在内存中创建一个新列表,这通常是不必要的开销。

更好的方法:

var filteredUsers = users.Where(u => u.IsActive);

仅在需要修改结果或方法要求时使用 ToList()

10. 读取文件前使用 File.Exists 在处理文件操作时防止未处理的异常。

示例:

if (File.Exists(path)) 
{
    var content = File.ReadAllText(path);
}

11. 使用 Environment.NewLine 代替 \n\r\n 在处理换行时确保跨平台兼容性。

示例:

string message = "Hi" + Environment.NewLine + "All!";

这可以防止在不同操作系统上运行时出现意外行为。

12. 处理时区时使用 DateTimeOffset 代替 DateTime DateTimeOffset 可防止与时区转换相关的问题。

示例:

DateTimeOffset now = DateTimeOffset.UtcNow;

这确保了在不同地点时间戳处理的一致性。

13. 为了可读性,优先使用 foreach 而非 for 使用 foreach 增强了可读性并避免了基于索引的错误。

示例:

foreach (var user in users) 
{
    Console.WriteLine(user.Name);
}

14. 使用 string.Join() 连接集合中的字符串 使用 string.Join() 来连接集合中的字符串,而不是通过循环连接。

示例:

var names = string.Join(", ", users.Select(u => u.Name));

这样更高效且更易读。

15. 使用字符串比较进行不区分大小写的匹配 在比较字符串时,避免因大小写差异导致的错误。

示例:

if (string.Equals(userInput, "admin", StringComparison.OrdinalIgnoreCase)) { ... }

这可以防止意外的匹配失败。

16. 对 IAsyncDisposable 对象使用 using 确保异步对象的正确资源释放。

示例:

await using var connection = new SqlConnection(connectionString);

这确保了数据库连接和其他可释放资源的正确清理。

17. 使用提前返回来简化代码 当条件满足时提前返回,避免深层嵌套。

示例:

if (input == null) return;

这使代码保持扁平且易读。

18. 在 API 调用中使用 Polly 实现重试策略 通过处理瞬时故障来提高弹性。

示例:

var policy = Policy.Handle<HttpRequestException>().Retry(3);

在进行不稳定的 API 请求时,Polly 很有帮助。

19. 使用 Fluent API 获得更好的可读性 使用 Fluent API 使代码更可读和直观。

示例:

var query = new QueryBuilder()
    .Select("Name", "City")
    .From("Users")
    .OrderBy("Name");

20. 编写自文档化的代码 代码应该清晰,无需过多的注释。

示例:

if (user.IsActive()) ProcessSubscription(user);

21. 对大型字符串操作使用 StringBuilder 在循环中修改字符串时避免性能问题。

示例:

var sb = new StringBuilder();
sb.Append("Hi").Append("All!");

22. 使用范围和索引进行更简洁的切片 使用 .. 操作符简化数组切片。

示例:

var lastTwo = numbers[^2..];

23. 使用 ?. 代替 null 检查 避免过多的 null 检查条件。

示例:

var city = user?.Address?.City;

24. 对不可变数据使用 record 减少 DTO 和只读对象的样板代码。

示例:

public record User(string Name, int Age);

25. 使用 HttpClientFactory 代替直接创建新的 HttpClient 实例 防止长时间运行的应用程序中的套接字耗尽。

示例:

var client = _httpClientFactory.CreateClient();

遵循这 25 个 C# 最佳实践将提高您代码的可读性、可维护性和性能。无论您是初学者还是经验丰富的开发者,这些技巧都将帮助您编写更整洁、更高效的 C# 代码。

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