Introduction
Let’s be honest: handling errors in C# has historically felts a bit like a game of “catch-me-if-you-can” with exceptions and nulls. But as the language evolves, we’re seeing a shift towards more expressive, functional patterns.
The Esox.SharpAndRusty library leans into this, bringing Rust-inspired reliability to .NET. At the heart of its ergonomic improvements is ExtendResult<T,TE>, a record based discriminated union alternative designed to make your code cleaner, safe, and – dare I say it – actually enjoyable to write.
What is ExtendedResult<T,TE>?
While the standard Result<T,E> is a high-performance read-only struct, ExtendedResult<T,TE> is built as a record-based discriminated union alternative. This design choice is a deliberate nod to developer ergonomics, enable seamless integration with modern C# features like pattern matching and LINQ.
Key Ergonomic Pillars
- Explicit State: It explicitly represents success and failure in your type signaturs, so you never have to guess if a method might blow up.
- Record Benefits: Because it is record-based, you get value-based equality and with-expression support for free.
- LINQ-friendly: It supports the full range of LINQ query comprehension including
fromandselect.
Pattern Matching: The End of the “If-Else” Hell
One of the most significat ergonomic leaps with ExtendedResult is how it leverages modern C# pattern matching. Instead of nesting if statements or checking success flags, you can use switch expression to handle all outcomes with zero ambiguity.
Becase ExtendedResult is built as a discriminated union alternative, the compiler helps ensure you have handled both the Success and Failure paths.
var message = result switch
{
ExtendedResult<User, Error>.Success(var user) => $"Welcome back, {user.Name}!",
ExtendedResult<User, Error>.Failure(var err) => $"Access denied: {err.Message}",
_ => "Unexpected state"
};
The syntax isn’t just “shorter” — it is safer. It forces you to acknowledge the error case as a first-class citizen rather than an afterthought tucked away in a catch block.
LINQ Query Syntax: Coding Like Poetry
If you find chaining Bind() calls a bit tedious, ExtendedResult offers full support for LINQ query syntax. This allows you to compose multiple operations that might fail into a single readable block of code.
If any step fails, the error propagates automatically and subsequent steps are skipped.
var finalResult = from x in GetInitialValue()
from y in ProcessValue(x)
from z in ValidateFinalStep(y)
select $"Final result: {z}";
The result of this block: either Ok("Final result: 42") or the first error encountered in the chain.
The Bottom Line
By shifting error handling from a “runtime surprise” to a “compile-time guarantee”, ExtendedResult significantly lowers the cognitive load of building complex systems. You spend less time debugging hidden exception and more time building features, knowing that the compiler forces you to acknowledge every failure path before it becomes a production headache.
Why it matters:
- Reliability: Explicit signatures communicate potential failures upfront, eliminating the guesswork in your API.
- Efficiency: Function composition via LINQ keeps your business logic linear and readable, avoiding the “pyramid of doom” created by nested checks.
- Context: When things do go wrong, the library’s rich
Errortype provides deep metadata, context chaining and 14 predefined error categories to help you diagnose the issue instantly.
In the end Esox.SharpAndRusty is not just about importing foreign patterns – it is about making C# feel as robust and predictable as a modern language should be.




