Consume
Methods that end the chain and hand you a plain value.
Everything on this page takes you out of the Option. To keep chaining, see Transform.
IsSome and IsNone
bool IsSome { get; }
bool IsNone { get; }The state, as a bool. Properties, not methods.
Option<string> maybeName = Option.Some("Laudna");
maybeName.IsSome; // true
maybeName.IsNone; // falseIsSomeAnd
bool IsSomeAnd(Predicate<T> predicate)There is a value and it passes the predicate.
Option<string> maybePatron = Option.Some("The Raven Queen");
maybePatron.IsSomeAnd(patron => patron.Length > 0); // trueIsNoneOr
There is no value, or the one there passes.
Match
Both branches, one plain value out. This is the default way to end a chain.
On a None: length is 0 — the onNone branch runs and onSome does not.
Match also has the state overload that saves the most, because a capturing call pays for two delegates. See Match saves the most.
Pattern matching with Deconstruct
From 7.0.0 the case types deconstruct, so C# pattern matching binds the value positionally.
Three Deconstruct methods exist across both types, and only three:
Some<T>
Deconstruct(out T value)
The contained value
Ok<TOk, TErr>
Deconstruct(out TOk value)
The Ok value
Err<TOk, TErr>
Deconstruct(out TErr error)
The error
Each is documented as never handing you null.
None has none, deliberately
There is nothing to bind, and option is None<string> already tests the case.
So option is None<string>(), with the parentheses, is a compile error rather than a redundant spelling. An empty positional pattern still needs a Deconstruct to bind against:
Write it without the parentheses.
You cannot deconstruct the monad itself
Deconstruct is on the case types, not on Option<T>. So this does not compile:
There is no state-plus-value tuple to destructure. Test the case first, then bind.
Where Match still wins
A switch expression over the closed hierarchy warns, even with both cases covered:
The hierarchy really is closed — an internal member stops anything outside the assembly deriving from Option<T> — but the compiler's exhaustiveness check has no knowledge of that idiom. Silencing the warning means an unreachable arm:
Match needs neither. It takes exactly two branches, both required, and returns a value with no warning to suppress.
So use Match when you want a value out of both cases, which is most of the time. Reach for a positional pattern in statement position — an if guarding a block, a switch statement, a when clause — where Match would mean wrapping statements in a lambda that returns nothing.
Unwrap
The value, or a throw.
On a None: throws UnwrapException.
UnwrapOr
The value, or the fallback you already have.
UnwrapOrElse
The same, but the factory runs only on a None. Use it when the fallback costs something to build.
UnwrapOrDefault
The value, or default(T).
On a value type this is the catch. The signature reads T?, but T is constrained notnull, so the ? is an annotation rather than a Nullable<T>. UnwrapOrDefault on an Option<int> hands you 0, and nothing tells you whether that 0 came from a Some or from the absent case. Reach for UnwrapOrNull there. WM2015 points this out for you.
UnwrapOrNull
The value, or null — a real Nullable<T>, so absence stays visible. An extension method, in Waystone.Monads.Options.Extensions.
Expect
Like Unwrap, but you supply the message the exception carries.
On a None: throws UnmetExpectationException carrying your message.
Use it where an absent value means a logic error rather than a runtime condition to recover from.
MapOr
Transforms the value, or returns your fallback. Unlike Map, it ends the chain.
MapOrElse
The same, building the fallback lazily.
Its state overload threads the same state through both delegates — see MapOrElse threads state through both delegates.
MapOrDefault
The same, falling back to default(TOut), so you write no fallback at all.
The signature reads TOut?, but TOut is constrained notnull, so on a value type that ? is an annotation and not a Nullable<TOut>. Map to an int and the absent case gives you 0, not null. That is what MapOrNull is for.
MapOrNull
The same, falling back to null. This one is on Option<T> itself, so it needs no extra using — unlike UnwrapOrNull, which is an extension.
Last updated
Was this helpful?