Prototype Design Pattern in C#: Cloning Objects Efficiently

Leader 25 60 128
calendar_todayschedule4 min read

Introduction

The Prototype Design Pattern is a creational design pattern that allows new objects to be created by copying an existing object (called a prototype) instead of creating them from scratch.

This pattern is particularly useful when:

  • Object creation is expensive or complex.
  • Many similar objects need to be created.
  • You want to avoid repeatedly initializing the same data.

Instead of using constructors every time, the application clones an existing object and modifies only the necessary properties.


Understanding the Prototype Pattern

The Prototype pattern works around a simple idea:

"Create new objects by cloning existing objects."

A prototype object acts as a template. When a new object is needed, the application copies the prototype and customizes it.

Structure

The following class diagram illustrates the Prototype Pattern:

Prototype Pattern Structure

Components:

  1. Prototype (BasicCar)

    • Declares a cloning method.
    • Defines the common interface for cloning.
  2. Concrete Prototypes (Nano, Ford)

    • Implement the cloning operation.
    • Return copies of themselves.
  3. Client (Program)

    • Uses prototypes to create new objects.

Prototype Pattern Example in C

Abstract Prototype

public abstract class BasicCar
{
    public string ModelName { get; set; }
    public int Price { get; set; }

    public static int SetPrice()
    {
        int price = 0;
        Random r = new Random();
        int p = r.Next(200000, 500000);

        price = p;
        return price;
    }

    public abstract BasicCar Clone();
}

Explanation

BasicCar acts as the prototype base class.

It contains:

  • Common properties (ModelName, Price)
  • A utility method for generating random prices
  • An abstract Clone() method that subclasses must implement

Concrete Prototype: Ford

public class Ford : BasicCar
{
    public Ford(string m)
    {
        ModelName = m;
    }

    public override BasicCar Clone()
    {
        return (Ford)this.MemberwiseClone();
    }
}

Explanation

The Ford class inherits from BasicCar and implements the cloning logic.

return (Ford)this.MemberwiseClone();

This creates a copy of the current object using the built-in MemberwiseClone() method.


Client Code

Console.WriteLine("***Prototype Pattern Demo***\n");

// Base or Original Copy
BasicCar nano_base = new Nano("Green Nano")
{
    Price = 100000
};

BasicCar ford_base = new Ford("Ford Yellow")
{
    Price = 500000
};

BasicCar bc1;

// Nano Clone
bc1 = nano_base.Clone();
bc1.Price = nano_base.Price + BasicCar.SetPrice();

Console.WriteLine(
    "Car is: {0}, and it's price is Rs. {1}",
    bc1.ModelName,
    bc1.Price);

// Ford Clone
bc1 = ford_base.Clone();
bc1.Price = ford_base.Price + BasicCar.SetPrice();

Console.WriteLine(
    "Car is: {0}, and it's price is Rs. {1}",
    bc1.ModelName,
    bc1.Price);

Console.ReadLine();

How the Program Works

Step 1: Create Prototype Objects

BasicCar nano_base = new Nano("Green Nano");
BasicCar ford_base = new Ford("Ford Yellow");

These objects become the prototypes.


Step 2: Clone Instead of Creating

bc1 = nano_base.Clone();

Rather than creating a new Nano, we copy the existing one.


Step 3: Customize the Clone

bc1.Price = nano_base.Price + BasicCar.SetPrice();

The cloned object receives a different price while keeping the original model information.


Step 4: Repeat for Other Car Types

bc1 = ford_base.Clone();

The same cloning mechanism works for any prototype implementation.


Understanding MemberwiseClone()

The Prototype pattern in C# often relies on:

this.MemberwiseClone();

MemberwiseClone() is a protected method of System.Object.

It creates a shallow copy of the current object.

var copy = this.MemberwiseClone();

What Gets Copied?

Value Types
int
bool
double
struct

These are copied by value.

Original ----> 100
Clone    ----> 100

Changes to one do not affect the other.


Reference Types
List<string>
Address
Customer
Array

Only the reference is copied.

Original ---> Address Object
Clone ------^

Both objects point to the same instance.


Shallow Copy vs Deep Copy

The following comparison summarizes the difference:

Type Meaning
Shallow Copy Copies fields, but references stay shared
Deep Copy Creates completely independent copies of all nested objects

Shallow Copy

public Person Clone()
{
    return (Person)this.MemberwiseClone();
}

Result:

Person A ---> Address
Person B ---^

Both persons share the same address object.


Deep Copy

public Person DeepClone()
{
    var copy = (Person)this.MemberwiseClone();

    copy.Address = new Address
    {
        City = this.Address.City
    };

    return copy;
}

Result:

Person A ---> Address A
Person B ---> Address B

Now each object has its own independent nested objects.


Is MemberwiseClone() Safe?

Yes, when:

  • Objects contain only value types.
  • Shared references are acceptable.
  • You manually clone reference-type members afterward.

Be Careful When:

  • Objects contain collections.
  • Objects contain nested objects.
  • Complete independence is required.

In those situations, implement a deep clone.


Benefits of the Prototype Pattern

1. Faster Object Creation

Cloning is often faster than constructing and initializing complex objects.

2. Reduces Repeated Initialization

Objects with many properties can be copied rather than rebuilt.

3. Simplifies Object Creation

Clients don't need to know all construction details.

4. Supports Runtime Object Creation

New objects can be created dynamically from existing prototypes.


Drawbacks

1. Deep Cloning Can Be Complex

Nested object graphs require extra cloning logic.

2. Shared References Can Cause Bugs

Using shallow copies incorrectly may lead to unexpected side effects.

3. Maintenance Overhead

Every new field may require updates to deep-cloning logic.


When Should You Use the Prototype Pattern?

Use Prototype when:

✅ Object creation is expensive

✅ Many similar objects are required

✅ Initialization logic is complex

✅ You need runtime object duplication

Examples include:

  • Game character templates
  • Vehicle configurations
  • Document templates
  • UI component libraries
  • Product catalogs

Conclusion

The Prototype Design Pattern is a powerful creational pattern that creates new objects by cloning existing ones. In C#, it is commonly implemented using MemberwiseClone(), which provides a fast and efficient way to perform shallow copies.

For simple objects, shallow cloning is often sufficient. However, when objects contain nested reference types, a deep clone should be implemented to ensure complete independence between the original object and its clone.

In the car example, Nano and Ford act as concrete prototypes, while BasicCar defines the cloning contract. The client can create new car instances efficiently by cloning existing prototypes instead of constructing them from scratch.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Understanding the Producer-Consumer Pattern in C#

Spyros - Apr 28

Understanding the Observer Pattern in C# with IObservable and IObserver

Spyros - Mar 11, 2025

Chain of Responsibility pattern

Spyros - Jan 19

Refactoring a Simple C# Method Step by Step

Spyros - May 6

Carter in a CQRS API, advantages and alternatives.

Spyros - Jan 7
chevron_left
8.5k Points213 Badges
Athens Greeceweb-partner.gr
48Posts
169Comments
114Connections
Passionate about building robust and scalable software solutions with a focus on .NET technologies. ... Show more

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!