C#如何实现对象状态的撤销和恢复

来源:AI大模型作者:辉辉头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#如何实现对象状态的撤销和恢复》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何实现对象状态的撤销和恢复》有用,将其分享出去将是对创作者最好的鼓励。

在C#开发过程中,很多业务场景需要支持对象状态的撤销与恢复功能,比如文本编辑器的撤销输入、绘图软件的重做操作、配置项的回滚修改等。备忘录模式可以在不暴露对象内部细节的前提下,记录对象的历史状态,满足这类需求。

C#如何实现对象状态的撤销和恢复

备忘录模式的核心角色

备忘录模式的实现需要三个核心角色配合,各自的职责明确,共同完成状态保存与恢复的逻辑:

  • 发起者(Originator):需要保存状态的对象,负责创建包含自身状态的备忘录,也可以通过备忘录恢复自身状态。
  • 备忘录(Memento):存储发起者的内部状态,防止外部直接访问其内部数据,通常只暴露给发起者和管理者。
  • 管理者(Caretaker):负责保存多个备忘录对象,提供对备忘录的存取操作,不修改备忘录的内容。

基础实现示例

下面通过一个文本编辑器的场景来演示完整的实现过程,文本编辑器需要支持输入内容的撤销操作。

1. 定义备忘录类

备忘录类用于存储发起者的状态,这里存储文本内容:

// 备忘录类,存储文本状态
public class TextMemento
{
    // 保存的文本内容
    public string Content { get; private set; }

    // 构造函数,初始化保存的内容
    public TextMemento(string content)
    {
        Content = content;
    }
}

2. 定义发起者类

发起者是文本编辑器本身,包含当前的文本内容,以及创建备忘录、从备忘录恢复状态的方法:

// 发起者类,对应文本编辑器
public class TextEditor
{
    // 当前文本内容
    public string CurrentContent { get; set; }

    // 创建备忘录,保存当前状态
    public TextMemento CreateMemento()
    {
        return new TextMemento(CurrentContent);
    }

    // 从备忘录恢复状态
    public void RestoreFromMemento(TextMemento memento)
    {
        if (memento != null)
        {
            CurrentContent = memento.Content;
        }
    }
}

3. 定义管理者类

管理者类负责维护备忘录的历史列表,支持添加、获取指定索引的备忘录:

using System.Collections.Generic;

// 管理者类,管理备忘录历史
public class Caretaker
{
    // 存储备忘录的列表
    private List<TextMemento> _mementoList = new List<TextMemento>();

    // 添加备忘录到历史列表
    public void AddMemento(TextMemento memento)
    {
        _mementoList.Add(memento);
    }

    // 获取指定索引的备忘录,索引从0开始
    public TextMemento GetMemento(int index)
    {
        if (index >= 0 && index < _mementoList.Count)
        {
            return _mementoList[index];
        }
        return null;
    }

    // 获取最后一个备忘录,用于撤销操作
    public TextMemento GetLastMemento()
    {
        if (_mementoList.Count == 0)
        {
            return null;
        }
        return _mementoList[_mementoList.Count - 1];
    }

    // 移除最后一个备忘录,当撤销后不需要保留该状态时可以使用
    public void RemoveLastMemento()
    {
        if (_mementoList.Count > 0)
        {
            _mementoList.RemoveAt(_mementoList.Count - 1);
        }
    }
}

4. 调用示例

下面模拟文本编辑器的使用过程,演示状态保存与撤销恢复的逻辑:

using System;

class Program
{
    static void Main(string[] args)
    {
        // 初始化文本编辑器和备忘录管理者
        TextEditor editor = new TextEditor();
        Caretaker caretaker = new Caretaker();

        // 第一次输入内容,保存状态
        editor.CurrentContent = "第一次输入的内容";
        Console.WriteLine("当前内容:" + editor.CurrentContent);
        caretaker.AddMemento(editor.CreateMemento());

        // 第二次输入内容,保存状态
        editor.CurrentContent = "第二次输入的内容";
        Console.WriteLine("当前内容:" + editor.CurrentContent);
        caretaker.AddMemento(editor.CreateMemento());

        // 第三次输入内容,保存状态
        editor.CurrentContent = "第三次输入的内容";
        Console.WriteLine("当前内容:" + editor.CurrentContent);
        caretaker.AddMemento(editor.CreateMemento());

        // 执行撤销操作,恢复到上一次的状态
        TextMemento lastMemento = caretaker.GetLastMemento();
        if (lastMemento != null)
        {
            editor.RestoreFromMemento(lastMemento);
            Console.WriteLine("撤销后内容:" + editor.CurrentContent);
            // 移除最后一个备忘录,避免重复撤销
            caretaker.RemoveLastMemento();
        }

        // 再次撤销,恢复到第一次输入后的状态
        lastMemento = caretaker.GetLastMemento();
        if (lastMemento != null)
        {
            editor.RestoreFromMemento(lastMemento);
            Console.WriteLine("再次撤销后内容:" + editor.CurrentContent);
        }
    }
}

实现注意事项

在实际使用备忘录模式时,需要注意以下几点:

  • 备忘录的存储内容需要根据发起者的状态确定,不要存储无关数据,避免占用过多内存。
  • 如果状态数据较大,可以考虑使用序列化方式存储备忘录,或者限制历史状态的保存数量。
  • 备忘录的访问权限要做好控制,除了发起者和管理者,其他对象不应该直接修改备忘录的内容。
  • 如果发起者状态变化频繁,需要合理控制保存状态的频率,避免性能问题。

扩展场景

除了文本编辑器的撤销功能,备忘录模式还可以应用在更多场景中:

  • 游戏进度的保存与加载,将玩家的游戏状态保存到备忘录,后续读取恢复。
  • 表单操作的回滚,用户修改表单后放弃修改,恢复到修改前的状态。
  • 事务操作的回滚,当操作失败时,恢复到事务开始前的系统状态。

C#备忘录模式Memento状态撤销状态恢复修改时间:2026-06-23 15:48:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。