DEV Community

Rafa Eslava
Rafa Eslava

Posted on

Why I Chose CRTP for My C# Result Pattern Library

🎯 The Problem That Started My Journey

I was diving deep into functional programming and Result patterns in C#, but I kept hitting the same wall: type information loss in fluent APIs.

// The problem I kept facing
Reason reason = new Error("Something went wrong")
    .WithMessage("Updated message")  // Returns Reason, not Error
    .WithTag("Code", 404);           // Can't call Error-specific methods
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ Discovering CRTP: The "Aha!" Moment

That's when I discovered the Curiously Recurring Template Pattern (CRTP). At first, it looked like magic:

// CRTP in action
public abstract class Reason<TReason> : Reason
    where TReason : Reason<TReason>
{
    public TReason WithMessage(string message) 
    { 
        Message = message; 
        return (TReason)this;  // Returns derived type!
    }
}
Enter fullscreen mode Exit fullscreen mode

Suddenly, everything clicked. The compiler could preserve type information through the entire fluent chain!


πŸ”§ Building REslava.Result

With CRTP as my foundation, I started building REslava.Result - a zero-dependency Result pattern library that solves the type preservation problem.

// Perfect type preservation with CRTP
Error error = new Error("Something went wrong")
    .WithMessage("Updated message")  // Returns Error
    .WithTag("Code", 404)           // Still Error - can chain more
    .WithTag("Field", "Email");     // Perfect fluent API
Enter fullscreen mode Exit fullscreen mode

This isn't just about pretty code - it's about compile-time safety and developer experience.


πŸš€ What I'm Learning Along the Way

Building this library has been an incredible learning journey:

  • Advanced C# patterns - CRTP, generics, covariance
  • Functional programming - Result patterns, monads, railway-oriented programming
  • Library design - API design, backwards compatibility, zero dependencies
  • Production thinking - Performance, testing, documentation

Every day brings new challenges and discoveries about what's possible in C#.


🎯 Why This Matters

Most Result libraries don't solve the fluent API type preservation problem. They either:

  • Accept the type loss (limiting)
  • Use complex workarounds (overly complicated)
  • Ignore fluent APIs altogether (missing opportunity)

CRTP provides an elegant solution that's both powerful and intuitive.


πŸ”— Come Learn With Me

I'm documenting this entire journey as I build REslava.Result:

GitHub
NuGet

I'd love to hear from others who have explored CRTP or are interested in functional programming in C#. What challenges have you faced? What solutions have you discovered?


πŸ“š Tags

csharp dotnet functionalprogramming crtp librarydevelopment resultpattern fluentapi

Top comments (0)