FailIf accumulates; Bind short-circuits
Now the idiom you'll write most. To validate, you chain guards with FailIf, then terminate with OrSuccess. The crucial, easy-to-miss detail: FailIf accumulates. It does not stop at the first failure. If three rules are broken, the Result comes back with all three errors, so the user fixes everything at once instead of playing whack-a-mole.
OrSuccess takes either a value or a factory Func<T>. Use the factory form (() => new ...) when building the value would be wrong or would throw if the guards had failed, since the factory only runs on the success path. Notice ejdpUniqueFlightKey! inside it: the null-forgiving ! is safe precisely because the FailIf above already proved it's non-null on this path.
Sometimes you need the opposite: step B depends on step A's value, so if A fails there's nothing to feed B. That's Bind. It short-circuits: on failure it returns the failure untouched; on success it runs the next step with the value. Use FailIf to gather independent rules, Bind to sequence dependent steps.
Try it yourself
Write a Create with an accumulating chain
Build the muscle: turn two rules into an accumulating factory. Model it on FlightNoteVo.Create above.
Tick every step to confirm you did it.
FailIf or Bind
You validate two independent fields on a request, and you want the caller to see BOTH errors if both are wrong. Which do you reach for?
The two chaining shapes
Lock the distinction in.
In one line each: when do you use FailIf and when do you use Bind?