Skip to main content
An expression-bodied method is a syntactic shorthand in C# that allows a method’s implementation to be defined using a single expression instead of a standard statement block. It utilizes the expression body definition operator (=>) to map the method signature directly to its evaluating expression, eliminating the need for curly braces ({}) and explicit return statements. At the Intermediate Language (IL) level, the C# compiler translates an expression-bodied method exactly as it would a traditional block-bodied method. It is strictly a compile-time syntactic sugar.

Syntax

Mechanics and Evaluation Rules

The behavior and compilation of an expression-bodied method depend on its signature: 1. Non-Void Return Types If the method declares a return type other than void, the expression to the right of the => operator must evaluate to a value that is implicitly convertible to the declared return type. The compiler automatically generates the underlying return statement. Async Methods: For async methods, the expression must be implicitly convertible to the method’s result type, not its declared return type. For example, if the declared return type is Task<string>, the await expression must evaluate to string. The compiler automatically handles the state machine generation and Task wrapping. 2. Void Return Types If the method declares a void return type, the expression must be a valid statement expression. In C#, statement expressions are restricted to method invocations, object creation (new), assignments, increment/decrement operations, and await expressions. 3. Throw Expressions A throw expression implicitly converts to any type. Therefore, it is a valid expression body for both void methods and non-void methods.

Executable Example

The following complete program demonstrates expression-bodied methods across various return types, modifiers, and expression categories.

Structural Limitations

Because the right side of the => operator must be a single evaluable expression, expression-bodied methods cannot contain:
  • Block-level control flow statements (if, while, for, foreach). Note: switch expressions and ternary operators (?:) are permitted because they evaluate to a value.
  • try-catch-finally blocks.
  • Multiple distinct statements separated by semicolons.
  • Standalone local variable declaration statements (e.g., int x = 5;). Note: Inline local variable declarations via out variables (e.g., int.TryParse(input, out int result)) and pattern matching (e.g., obj is string s) are fully supported as they are part of a single expression.
Tired of Poor C# Skills? Fix That With Deep Grasping!Learn More