编辑
2025-09-18
C#
00

目录

引言
在C#中创建不可变对象
使用只读属性
将字段设置为只读
在方法中返回新实例
不可变对象的优点
不可变对象的缺点
结论

引言

在面向对象编程领域中,不变性的概念在并发和数据完整性至关重要的环境中扮演着关键角色。一旦创建,不可变对象不允许其状态被更改,因此提供了诸如增强的线程安全性和减少调试复杂性等多个优点。本文深入探讨了在C#中创建不可变对象的方法,并通过实际例子讨论了它们的利弊。

在C#中创建不可变对象

使用只读属性

在C#中强制实施不变性的一种有效方式是使用只读属性。这些属性必须在对象创建时设置,并且之后不能修改。这种方法不仅确保了数据完整性,还简化了对象模型。

示例:

C#
public class Employee { public string Name { get; } public int Age { get; } public Employee(string name, int age) { Name = name; Age = age; } public void Print() { Console.WriteLine($"Name: {Name}, Age: {Age}"); } } internal class Program { static void Main(string[] args) { Employee employee = new Employee("rick",99); employee.Print(); Console.ReadKey(); } }

image.png

在这个例子中,NameAge 是只读属性,只能通过构造函数设置,并且之后是不可变的。

将字段设置为只读

另一种方法是将字段声明为 readonly。这个关键字确保字段只能在声明时或在类的构造函数中赋值。

示例:

C#
public class Book { public readonly string Title; public readonly string Author; public Book(string title, string author) { Title = title; Author = author; } }

这里,TitleAuthorreadonly 字段,确保了 Book 实例的不变性。

在方法中返回新实例

为了维护不变性,看似可能修改对象状态的方法应该返回一个带有修改值的新对象实例。

示例:

C#
public class Rectangle { public readonly int Width; public readonly int Height; public Rectangle(int width, int height) { Width = width; Height = height; } public Rectangle Resize(int newWidth, int newHeight) { return new Rectangle(newWidth, newHeight); } }

image.png

在这种情况下,Resize 不会改变现有的 Rectangle 实例,而是返回一个具有指定尺寸的新实例。

不可变对象的优点

  1. 线程安全: 由于不可变对象在创建后状态无法更改,因此天然地防止了竞态条件,无需同步机制。
  2. 代码简化: 当对象是不可变的时候,代码更易于维护和推理,因为对象状态不会出现意外变化。
  3. 调试: 不可变对象的状态一致性简化了调试,因为对象的生命周期中状态保持不变。
  4. 共享和缓存: 由于不可变对象无法被修改,它们可以自由地在线程之间共享,无需担心数据损坏,使它们成为缓存的绝佳选择。

不可变对象的缺点

  1. 性能开销: 每次状态变更都需要创建新对象,可能引入性能开销,特别是在复杂对象中。
  2. 内存使用: 不可变对象可能会消耗更多内存,因为每次状态变更都需要创建新对象。
  3. 更新的复杂性: 管理更新可能变得繁琐,特别是在需要频繁修改的对象中。

结论

在数据完整性和线程安全至关重要的场景中,使用C#中的不可变对象提供了显著的优势。通过遵循本指南概述的策略,开发者可以创建健壮可靠的应用程序。虽然在性能和内存使用方面有一些权衡,但不变性的好处通常超过这些缺点,特别是在高并发环境中。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!