当开发者谈论编写"整洁的".NET代码时,他们通常指的是可读、可维护且无bug的代码。但整洁的代码还应该意味着快速、高效且意图明确。许多C#开发者忽略了那些能够悄无声息地提升性能、减少内存压力并使代码更抗误用的语言和框架特性。
在本文中,我们将介绍5个实用技巧,这些技巧可能不常被讨论,但能在实际项目中产生显著差异。这些不是华而不实的技巧;而是经验丰富的工程师悄悄使用的那种小而深思熟虑的更改,以保持其应用程序的精简和可预测性。
1. 使用泛型约束避免装箱
错误方式:
如果使用没有约束的泛型方法,在处理值类型时很容易陷入装箱。这会损害性能并增加不必要的分配。
public static bool AreEqual<T>(T a, T b)
{
return a.Equals(b); // 如果T是值类型且没有约束,会导致装箱
}在这里,当T是int等值类型时,a.Equals(b)会导致装箱,因为Equals是在object上调用的。
更好的方式:
使用where T : struct或where T : IEquatable<T>约束来完全避免装箱。
public static bool AreEqual<T>(T a, T b) where T : IEquatable<T>
{
return a.Equals(b); // 无装箱
}为何重要:装箱对性能的影响是悄无声息但致命的。这个小约束使你的泛型真正实现高性能。
2. 使用.TryGetNonEnumeratedCount()最小化LINQ分配
错误方式:
在IEnumerable上调用.Count()总是会遍历集合,除非它是List或Array。
var count = myEnumerable.Count(); // 可能触发完整遍历更好的方式:
使用.TryGetNonEnumeratedCount(out count)在可能的情况下获取计数而不强制枚举。
if (!myEnumerable.TryGetNonEnumeratedCount(out var count))
{
count = myEnumerable.Count(); // 必要时回退
}为何重要:该方法在计数频繁但实际枚举成本高的热路径中避免了不必要的工作。
3. 使用init访问器实现不可变对象设置
错误方式:
将所有属性设置为set意味着它们可以在任何时间点被修改,这可能导致意外的副作用。
public class User
{
public string Name { get; set; }
}更好的方式:
使用init只允许在初始化期间进行属性赋值。
public class User
{
public string Name { get; init; }
}
var user = new User { Name = "Ali" }; // 有效
// user.Name = "Bob"; // 编译错误为何重要:init带来了不可变性的清晰度,而无需强制你为每个赋值使用构造函数。
4. 优先使用readonly record struct实现轻量级不可变值类型
错误方式:
将小型不可变类型定义为类会增加堆分配和GC压力。
public record Point(int X, int Y);默认情况下这是一个类,意味着它是引用类型。
更好的方式:
使用readonly record struct实现不可变的值语义。
public readonly record struct Point(int X, int Y);为何重要:你获得了不可变性、值类型性能,并且没有意外的堆分配。
5. 使用ref readonly参数高效传递大型结构体
错误方式:
按值传递大型结构体会复制整个数据。
public static double CalculateVolume(Box box) // 复制box
{
return box.Length * box.Width * box.Height;
}更好的方式:
使用ref readonly传递它们以避免复制,同时仍防止修改。
public static double CalculateVolume(ref readonly Box box)
{
return box.Length * box.Width * box.Height;
}为何重要:这保持了高性能并防止意外写入结构体。非常适合大型不可变数据结构。
掌握.NET不是要记住每个API;而是要了解何时以及为何使用正确的工具。我们在这里介绍的功能单独看起来可能很小,但它们共同帮助创建更快、更可靠和更可维护的代码。随着时间的推移,这些习惯会累积成一个更容易演进且更难破坏的代码库。
下次你打开编辑器时,尝试应用这些技巧中的至少一个。你可能不会立即注意到差异,但你未来的自己和你的团队肯定会感受到。
5358

被折叠的 条评论
为什么被折叠?



