Creation
The factory methods that build a Result<TOk, TErr>.
Result.Ok and Result.Err
Result<TOk, TErr> Result.Ok<TOk, TErr>(TOk value)
Result<TOk, TErr> Result.Err<TOk, TErr>(TErr error)Supply both type parameters when you use your own error type.
Result<int, string> ok = Result.Ok<int, string>(1);
Result<int, string> err = Result.Err<int, string>("Something went wrong...");Neither an Ok nor an Err can hold null. Pass one and you get an ArgumentNullException. Every factory funnels through the same guard.
Result.Ok<string, Error>(null!); // throwsNew in 5.5.0. Before that, an Ok could hold null and the null surfaced later as a NullReferenceException in your own code. TOk and TErr are constrained notnull, so the compiler already warned you; now the runtime agrees.
A default value is fine and always has been. Result.Ok<int, string>(0) is an Ok holding 0. Only null is rejected.
The single-type-parameter overloads
Result<TOk, Error> Result.Ok<TOk>(TOk value)
Result<TOk, Error> Result.Err<TOk>(Error error)If you are happy with the built-in Error type, leave TErr off and it defaults to Error.
Result<int, Error> ok = Result.Ok<int>(1);
Result<int, Error> err = Result.Err<int>(
new Error("MyCode", "Something went wrong..."));From a generated catalog
Mark an enum with [ErrorCodeCatalog] and the source generator gives you a factory per member, with the message required.
Result.Try
Runs a factory that might throw, and asks one question: did it hand back a value you can work with?
On a throw: the exception is caught, sent to your configured exception logger, and onError runs.
On null: onError runs too, passed an ArgumentNullException naming the factory argument. Nothing is logged, because nothing threw.
That last case is the one place a null does not throw. Try exists so you can hand over a delegate and learn whether a workable value came back without wrapping the call yourself — so it turns the null into an Err for you.
A cancellation is not caught. Try and TryAsync let an OperationCanceledException propagate. See Configuration.
Do not pass an async factory to Try. It compiles, gives you a Result<Task<T>, E>, and catches nothing. Use TryAsync. WM1011 reports every occurrence.
Defaulting to Error
Converts the exception with Error.FromException, so you pass no onError delegate.
Result.TryAsync
The same, for a factory that returns a Task. See Async.
Passing state to the factory
Try and TryAsync each take an optional first argument that they hand to your factory. Use it to keep the factory from capturing:
See State overloads for why this matters.
Last updated
Was this helpful?