Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The declaration pattern in C# is a pattern matching construct that checks whether a runtime value is compatible with a specified type and, upon a successful match, binds the converted result to a newly declared local variable. It combines type testing and safe casting into a single operation.

Syntax

The syntax of the declaration pattern itself consists strictly of a type and a designation (a variable name or a discard):
Type variableName
  • Type: The target type to match against.
  • variableName: The identifier for the newly declared pattern variable. A discard (_) can be used if the bound value is not needed.

Contexts of Use

Because patterns do not evaluate themselves, the declaration pattern must be hosted within a pattern-matching construct. The primary contexts include:
  1. The is Operator: Evaluates the pattern and yields a boolean result.
  2. switch Statements: Evaluates the pattern to determine branch execution.
  3. switch Expressions: Evaluates the pattern to return a corresponding expression arm.
object data = "Runtime String";

// Context 1: 'is' operator expression
if (data is string stringData) 
{ 
    Console.WriteLine(stringData); 
}

// Context 2: 'switch' statement
switch (data)
{
    case int intData:
        break;
}

// Context 3: 'switch' expression
var result = data switch
{
    DateTime dateData => dateData.ToString(),
    _ => "Unknown"
};

Execution Mechanics

When an enclosing construct evaluates an input value against a declaration pattern, the runtime performs the following sequence:
  1. Type Testing: The runtime checks if the input value is of type Type (or derived from Type).
  2. Null Checking: If the input value is null, the pattern match fails, even if Type is a reference type or a nullable value type.
  3. Binding: If the type test succeeds, the runtime casts the value to Type and assigns it to variableName.
  4. Construct Resolution: The pattern reports match success or failure to the enclosing construct. The construct then dictates the control flow (e.g., the is operator yields true, or a switch routes to a specific case). The pattern itself does not yield a boolean value.

Scope and Definite Assignment

The declaration pattern introduces a pattern variable into the enclosing lexical scope. However, C# enforces flow-dependent definite assignment rules. The variable is only accessible and considered initialized in code paths where the compiler can guarantee the pattern match succeeded.
object data = "Runtime String";

if (data is string stringData)
{
    // stringData is definitely assigned and accessible here.
    Console.WriteLine(stringData.Length);
}

// stringData is technically in scope here, but accessing it results in 
// compiler error CS0165 (Use of unassigned local variable) because 
// it is not definitely assigned in this execution path.
If the pattern match dictates an early exit (such as through logical negation), the definite assignment flows to the alternative branch based on compiler flow analysis:
if (!(data is string stringData))
{
    // stringData is unassigned here.
    return;
}

// stringData is definitely assigned here due to the early exit above.
Console.WriteLine(stringData.Length);

Type Handling Characteristics

  • Reference Types: Performs standard polymorphic type checking. The match succeeds if the input’s runtime type is exactly the target type or derives from it.
  • Value Types and Unboxing: The pattern handles unboxing automatically. If the input is a boxed int (e.g., stored in an object reference), evaluating it against the pattern int i will successfully unbox the value, allocate i on the stack, and assign the unboxed value to it.
  • Nullable Value Types: Matching a nullable value type expression against its underlying non-nullable type (e.g., evaluating an int? input against the pattern int i) successfully extracts the underlying value, provided the input is not null.
Master C# with Deep Grasping Methodology!Learn More