Builder & Prototype Design Patterns with Generics in C#

✅ Introduction

In software design, object creation often becomes complex—especially when handling deeply nested or repeatable structures. Two powerful creational design patterns in C#, the Builder Pattern and Prototype Pattern, solve these challenges elegantly.

When combined with generics, these patterns provide a type-safe, reusable, and flexible approach to object construction and cloning.

In this article, you’ll learn:

  • The Builder Pattern with Generics
  • The Prototype Pattern with Generics
  • Why generics improve these patterns
  • Real-world examples in C#
  • A bonus: combining Builder + Prototype with Generics

🧱 1. Builder Pattern with Generics in C#

🤔 What is the Builder Pattern?

The Builder Pattern is used to construct complex objects step by step.
It separates object construction from representation, making it easy to reuse the same building logic for different configurations.

🎯 Real-Life Example: Building a Computer

public class Computer
{
    public string CPU { get; set; }
    public string RAM { get; set; }
    public string Storage { get; set; }

    public override string ToString()
    {
        return $"CPU: {CPU}, RAM: {RAM}, Storage: {Storage}";
    }
}

🛠️ Generic Builder Implementation

public class Builder<T> where T : new()
{
    private readonly T _instance = new T();

    public Builder<T> Set(Action<T> setter)
    {
        setter(_instance);
        return this;
    }

    public T Build() => _instance;
}

✅ Usage Example

var computer = new Builder<Computer>()
    .Set(c => c.CPU = "Intel i7")
    .Set(c => c.RAM = "16GB")
    .Set(c => c.Storage = "512GB SSD")
    .Build();

Console.WriteLine(computer);
// Output: CPU: Intel i7, RAM: 16GB, Storage: 512GB SSD

🔁 2. Prototype Pattern with Generics in C#

🤔 What is the Prototype Pattern?

The Prototype Pattern allows you to clone existing objects instead of creating new ones from scratch.
This is especially useful when object creation is expensive or requires extensive configuration.

🧪 Generic Prototype Interface

public interface IPrototype<T>
{
    T Clone();
}

🧾 Implementing in a Model: Document

public class Document : IPrototype<Document>
{
    public string Title { get; set; }
    public string Content { get; set; }

    public Document Clone()
    {
        return (Document)this.MemberwiseClone(); // Shallow copy
    }

    public override string ToString()
    {
        return $"Title: {Title}, Content: {Content}";
    }
}

✅ Usage Example

var original = new Document { Title = "Report", Content = "Q1 Results" };
var copy = original.Clone();
copy.Title = "Copied Report";

Console.WriteLine(original); // Title: Report, Content: Q1 Results
Console.WriteLine(copy);     // Title: Copied Report, Content: Q1 Results


🎯 Why Use Generics in Design Patterns?

FeatureBenefit
✅ ReusabilityOne generic builder works for any class
✅ Type SafetyCompile-time checks prevent runtime errors
✅ Cleaner CodeAvoids duplication for each object type
✅ FlexibilityWorks with interfaces, constraints, and more

🧠 Bonus: Combining Builder & Prototype with Generics

You can even merge both patterns into one powerful reusable class:

public class ClonableBuilder<T> where T : IPrototype<T>, new()
{
    private T _instance = new T();

    public ClonableBuilder<T> Set(Action<T> setter)
    {
        setter(_instance);
        return this;
    }

    public T Build() => _instance;
    public T Clone() => _instance.Clone();
}

This allows step-by-step object creation and cloning in the same class.

📌 Summary

PatternPurposeRole of Generics
BuilderStep-by-step object creationOne builder for multiple types
PrototypeObject cloningType-safe clone method
CombinedCreation + cloningCleaner, reusable design

🏁 Final Thoughts

Using generics with design patterns like Builder and Prototype makes your C# code modular, reusable, and maintainable.
Whether you’re designing configuration objects, UI templates, or domain models, this approach scales beautifully in real-world projects.

Leave a Comment