Skip to content

Enforce a method precondition

Fail fast on invalid arguments or state, triggered when called at the top of a public method by consumers and by intra-library callers (IEnumerableExtensions, DictionaryExtensions, UriExtensions).

Field Value
Operation ID OP-017
Trigger Called at the top of a public method by consumers and by intra-library callers (IEnumerableExtensions, DictionaryExtensions, UriExtensions)
Inputs The parameter value, the parameter name, or a boolean / Func<bool> condition
Outputs The validated value (fluent) or void; throws on violation
Primary components `SAIF.Enforce — ArgumentNotNull<T>, ArgumentNotNullOrEmpty, ArgumentNotNullOrWhiteSpace, NotNull<T>, True (4 overloads)`
Entry point Common/SAIF.Common/Classes/Enforce.cs

Steps

  1. ArgumentNotNull first validates its own parameterName argument: if null or whitespace, throw ArgumentNullException("parameterName"). (BR-038)
  2. If the parameter itself is null (via GenericExtensions.IsNull), throw ArgumentNullException(parameterName); otherwise return the parameter so the call can be chained. (BR-039)
  3. ArgumentNotNullOrEmpty runs steps 1-2 first, then throws ArgumentException("Parameter ({name}) cannot be null or empty.") when the string is empty. (BR-039, BR-040)
  4. ArgumentNotNullOrWhiteSpace runs steps 1-2 first, then throws ArgumentException("Parameter ({name}) cannot be null or white space.") when the string trims to nothing. (BR-039, BR-041)
  5. NotNull<T> delegates to GenericExtensions.IfNullThrow<T, InvalidOperationException> with the message "The type {FullName} cannot be null." — used for state, not arguments. (BR-042)
  6. True<T>(bool) / True<T>(Func<bool>) throw a new parameterless T : Exception when the condition is false; True(bool, Exception) / True(Func<bool>, Exception) throw the caller-supplied exception instance. (BR-043)

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start(["Guard called at top<br>of a method"]) --> P1["ArgumentNotNull validates<br>parameterName"]
    P1 --> C1{"parameterName null<br>or whitespace?"}
    C1 -->|Yes| ErrName(["Throw ArgumentNullException<br>for parameterName"])
    C1 -->|No| P2["Check parameter<br>via IsNull"]
    P2 --> C2{"Parameter is null?"}
    C2 -->|Yes| ErrParam(["Throw ArgumentNullException<br>for parameterName"])
    C2 -->|No| P3["Return parameter<br>for chaining"]
    P3 --> C3{"Called via<br>ArgumentNotNullOrEmpty?"}
    C3 -->|Yes, string empty| ErrEmpty["Throw ArgumentException<br>cannot be null or empty"]
    C3 -->|No| C4{"Called via ArgumentNotNull<br>OrWhiteSpace?"}
    C4 -->|Yes, trims to nothing| ErrWhite["Throw ArgumentException<br>cannot be null or white space"]
    C4 -->|No| C5{"Called via NotNull<T>?"}
    C5 -->|Yes, state is null| ErrState["Delegate to IfNullThrow<br>throw InvalidOperationException"]
    C5 -->|No| C6{"Called via True variant?"}
    C6 -->|Condition false| ErrTrue["Throw parameterless T<br>or caller-supplied exception"]
    C6 -->|Condition true| End(["Guard passes"])

Sources

  • Common/SAIF.Common/Classes/Enforce.cs