Memento Pattern in C#: Definition, Examples, Pros, Cons, and Use Cases

Memento Pattern in C#: Definition, Examples, Pros, Cons, and Use Cases

The Memento pattern in C# is a behavioral design pattern that captures and restores an object's internal state without exposing its implementation details.

The Memento pattern allows an object to save its current state into a separate snapshot object called a memento. Later, the object can restore itself to that previously saved state when needed. This pattern helps implement undo/redo functionality while preserving encapsulation. The main participants are the Originator (state owner), the Memento (state snapshot), and the Caretaker (state manager). In C#, the Memento pattern is commonly used in editors, games, transaction systems, workflow systems, and history management features.

Why We Use Memento Pattern in C#?

We use the Memento pattern in C# to:

• Save and restore object states
• Implement undo/redo functionality
• Preserve encapsulation
• Track object history
• Roll back failed operations
• Simplify state recovery logic
• Manage snapshots safely
• Reduce direct exposure of internal object data

When Should We Use Memento Pattern in C#?

The Memento pattern should be used when:

• Object states must be restored later
• Undo/redo functionality is required
• State history tracking is needed
• Direct state exposure should be avoided
• Checkpoint systems are required
• Transaction rollback mechanisms are needed
• Complex object states need snapshot support

Common Programming Problems Solved by Memento Pattern

• Undo/redo systems
• Save/load game progress
• Transaction rollback
• Text editor history
• Configuration recovery
• Workflow checkpointing
• State versioning
• Temporary state backups

Structure of Memento Pattern in C#

Typical participants:

• Originator
• Memento
• Caretaker
• Client

Basic workflow:

• Originator creates a snapshot
• Caretaker stores snapshot
• Object state changes
• Caretaker restores snapshot when needed

Momento Pattern Examples in C#

Example 1: Text Editor Undo System

A text editor should support undo functionality.

using System;
using System.Collections.Generic;

public class TextMemento
{
    public string Content { get; }

    public TextMemento(string content)
    {
        Content = content;
    }
}

public class TextEditor
{
    public string Content { get; set; }

    public TextMemento Save()
    {
        return new TextMemento(Content);
    }

    public void Restore(TextMemento memento)
    {
        Content = memento.Content;
    }
}

public class History
{
    private Stack<TextMemento> history = new Stack<TextMemento>();

    public void Save(TextMemento memento)
    {
        history.Push(memento);
    }

    public TextMemento Undo()
    {
        return history.Pop();
    }
}

public class Program
{
    public static void Main()
    {
        TextEditor editor = new TextEditor();
        History history = new History();

        editor.Content = "Version 1";
        history.Save(editor.Save());

        editor.Content = "Version 2";

        Console.WriteLine(editor.Content);

        editor.Restore(history.Undo());

        Console.WriteLine(editor.Content);
    }
}

Example 2: Game Save System

A game should save and restore player progress.

using System;

public class GameMemento
{
    public int Level { get; }
    public int Health { get; }

    public GameMemento(int level, int health)
    {
        Level = level;
        Health = health;
    }
}

public class Game
{
    public int Level { get; set; }
    public int Health { get; set; }

    public GameMemento Save()
    {
        return new GameMemento(Level, Health);
    }

    public void Restore(GameMemento memento)
    {
        Level = memento.Level;
        Health = memento.Health;
    }
}

public class Program
{
    public static void Main()
    {
        Game game = new Game();

        game.Level = 5;
        game.Health = 80;

        GameMemento save = game.Save();

        game.Level = 10;
        game.Health = 20;

        game.Restore(save);

        Console.WriteLine($"Level: {game.Level}");
        Console.WriteLine($"Health: {game.Health}");
    }
}

Example 3: Bank Transaction Rollback

A failed transaction should restore previous account balance.

using System;

public class AccountMemento
{
    public decimal Balance { get; }

    public AccountMemento(decimal balance)
    {
        Balance = balance;
    }
}

public class BankAccount
{
    public decimal Balance { get; private set; }

    public BankAccount(decimal balance)
    {
        Balance = balance;
    }

    public void Deposit(decimal amount)
    {
        Balance += amount;
    }

    public void Withdraw(decimal amount)
    {
        Balance -= amount;
    }

    public AccountMemento Save()
    {
        return new AccountMemento(Balance);
    }

    public void Restore(AccountMemento memento)
    {
        Balance = memento.Balance;
    }
}

public class Program
{
    public static void Main()
    {
        BankAccount account = new BankAccount(1000);

        AccountMemento backup = account.Save();

        account.Withdraw(900);

        Console.WriteLine("Current Balance: " + account.Balance);

        account.Restore(backup);

        Console.WriteLine("Restored Balance: " + account.Balance);
    }
}

Most Known Real-World Use Cases in C#

• Text editor undo/redo systems
• Game save/load systems
• Database transaction rollback
• Drawing applications
• Workflow recovery systems
• IDE history management
• Form state recovery
• Snapshot/version management

Advantages of Memento Pattern in C#

• Preserves encapsulation
• Simplifies undo/redo implementation
• Enables state restoration
• Supports rollback operations
• Keeps state snapshots isolated
• Improves recovery mechanisms
• Reduces direct state manipulation
• Makes history tracking easier

Disadvantages (Weak Points) of Memento Pattern in C#

• Can consume large memory for many snapshots
• Snapshot management may become complex
• Large objects increase storage costs
• Caretaker can grow significantly
• Performance overhead in frequent saves
• Difficult with deeply nested object graphs
• May require cloning complex structures

Comparison with Similar Patterns

Pattern Main Purpose State Storage Encapsulation Typical Usage Main Difference from Memento
Memento Save and restore object state Snapshot objects Strong Undo/redo, rollback Focuses on state preservation and restoration
State Change behavior by internal state Separate state classes Moderate Workflow systems, UI states Changes behavior dynamically instead of saving snapshots
Command Encapsulate operations Command history Strong Task queues, undo systems Stores actions rather than full object states
Prototype Clone objects Object copies Moderate Object duplication Focuses on cloning instead of historical restoration
Flyweight Reduce memory usage Shared state Low Caching systems Optimizes memory instead of preserving history

Simplified UML-Style Structure

Component Responsibility
Originator Creates and restores snapshots
Memento Stores object state snapshot
Caretaker Manages saved snapshots
Client Requests save or restore operations