Replaces an expression body with a block holding the equivalent statement. The reverse of Convert to Expression Body.
Target
The declaration, by symbol: a method, constructor, operator, property, indexer or accessor (M:Sample.set_Name(System.String) for a setter). A local function, which has no symbol id, by a caret on its name.
Precondition
The declaration has an expression body.
When the declaration returns a value, => expression; becomes { return expression; }: methods and local functions with a return type, operators, conversions and get accessors. When it does not, the expression becomes a statement of its own: void methods, constructors, finalizers, set, init, add and remove accessors, and async methods returning Task or ValueTask, which await rather than return. => throw expression; becomes { throw expression; }.An expression-bodied property or indexer gets an accessor list with a get accessor holding the block. The block is laid out on lines of its own. An expression spanning several lines keeps its line breaks, shifted to sit under the statement.
Preserved
Behaviour: the block means exactly what the expression body did. Comments above the declaration stay there; a comment after the semicolon stays at the end of the statement.
Limitations
An auto-property's accessors have no body to expand, and an abstract member none at all; both are refused.
Error codes
Code Meaning already-block-bodythe declaration already has a block body no-bodythe declaration has no body, such as an abstract method or an auto-property not-a-member-with-bodythe target is not a method, property, accessor, constructor, operator or local function
Cases
Expand all · Collapse all
Diffs show each file from before to after .
/*[*/ … /*]*/ marks a selection and /*^*/ a caret; the runner removes them before the refactoring runs.
# accessorOne expression-bodied accessor gets a block; the other accessor is left alone
success
Target symbol M:Sample.set_Name(System.String)
Sample.cs modified
1 1 public class Sample 2 2 { 3 3 private string _name = "" ; 4 4 5 5 public string Name 6 6 { 7 7 get => _name; 8 − set => _name = value .Trim (); 8 + set 9 + { 10 + _name = value .Trim (); 11 + } 9 12 } 10 13 }
View fixture on GitHub
# already-block-body-rejectedRefuses a member that already has a block body
refusal
Target symbol M:Sample.Total
Refuses already-block-body; every file is left unchanged
Sample.cs input
1 public class Sample 2 { 3 private int _a; 4 5 public int Total () 6 { 7 return _a; 8 } 9 }
View fixture on GitHub
# async-methodsAn async method returning Task awaits in a statement rather than returning the awaited value
success
Target symbol M:Sample.SaveAsync
Sample.cs modified
1 1 using System .Threading .Tasks ;2 2 3 3 public class Sample 4 4 { 5 − public async Task SaveAsync () => await Task .Delay (10 ); 5 + public async Task SaveAsync () 6 + { 7 + await Task .Delay (10 ); 8 + } 6 9 7 10 public async Task <int > CountAsync () => await Task .FromResult (3 ); 8 11 }
View fixture on GitHub
# async-returning-valueAn async method returning Task<T> returns the awaited value
success
Target symbol M:Sample.CountAsync
Sample.cs modified
1 1 using System .Threading .Tasks ;2 2 3 3 public class Sample 4 4 { 5 − public async Task <int > CountAsync () => await Task .FromResult (3 ); 5 + public async Task <int > CountAsync () 6 + { 7 + return await Task .FromResult (3 ); 8 + } 6 9 }
View fixture on GitHub
# auto-property-rejectedRefuses an auto-property, whose accessors have no bodies to expand
refusal
Target symbol P:Sample.Name
Refuses no-body; every file is left unchanged
Sample.cs input
1 public class Sample 2 { 3 public string Name { get ; set ; } = "" ; 4 }
View fixture on GitHub
# constructorAn expression-bodied constructor with an initializer gets a block
success
Target symbol M:Shop.Order.#ctor(System.Int32)
Order.cs modified
1 1 namespace Shop ;2 2 3 3 public class Entity 4 4 { 5 5 } 6 6 7 7 public class Order : Entity 8 8 { 9 9 private readonly int _quantity; 10 10 11 − public Order (int quantity) : base () => _quantity = quantity; 11 + public Order (int quantity) : base () 12 + { 13 + _quantity = quantity; 14 + } 12 15 }
View fixture on GitHub
# indexerAn expression-bodied indexer becomes an indexer with a get accessor
success
Target symbol P:Sample.Item(System.Int32)
Sample.cs modified
1 1 public class Sample 2 2 { 3 3 private readonly int [] _items = new int [4 ]; 4 4 5 − public int this [int index] => _items[index]; 5 + public int this [int index] 6 + { 7 + get 8 + { 9 + return _items[index]; 10 + } 11 + } 6 12 }
View fixture on GitHub
# local-functionAn expression-bodied local function, targeted by a caret on its name, gets a block
success
Target Sample.cs, the /*^*/ caret
Sample.cs modified
1 1 public class Sample 2 2 { 3 3 public int Total (int [] prices) 4 4 { 5 5 var sum = 0 ; 6 6 foreach (var price in prices) 7 7 sum += WithTax (price); 8 8 return sum; 9 9 10 − static int /*^*/ WithTax (int price) => price * 120 / 100 ; 10 + static int WithTax (int price) 11 + { 12 + return price * 120 / 100 ; 13 + } 11 14 } 12 15 }
View fixture on GitHub
# multi-line-expressionAn expression spanning several lines keeps its line breaks, indented under the return
success
Target symbol M:Sample.Total(System.Collections.Generic.List{System.Int32})
Sample.cs modified
1 1 using System .Collections .Generic ;2 2 using System .Linq ;3 3 4 4 public class Sample 5 5 { 6 − public int Total (List <int > items) => items 7 − .Where (i => i > 0 ) 8 − .Sum (); 6 + public int Total (List <int > items) 7 + { 8 + return items 9 + .Where (i => i > 0 ) 10 + .Sum (); 11 + } 9 12 }
View fixture on GitHub
# no-body-rejectedRefuses an abstract method, which has no body
refusal
Target symbol M:Shape.Area
Refuses no-body; every file is left unchanged
Shape.cs input
1 public abstract class Shape 2 { 3 public abstract double Area (); 4 }
View fixture on GitHub
# not-a-member-rejectedRefuses a field, which has no body
refusal
Target symbol F:Sample._total
Refuses not-a-member-with-body; every file is left unchanged
Sample.cs input
1 public class Sample 2 { 3 private int _total; 4 5 public int Total => _total; 6 }
View fixture on GitHub
# nullable-contextA method returning a nullable reference converts without new warnings
success
Target symbol M:Sample.Find(System.String)
Project nullable enable
Sample.cs modified
1 1 using System .Collections .Generic ;2 2 3 3 public class Sample 4 4 { 5 5 private readonly Dictionary <string , string > _names = new (); 6 6 7 − public string ? Find (string key) => _names.TryGetValue (key, out var name) ? name : null ; 7 + public string ? Find (string key) 8 + { 9 + return _names.TryGetValue (key, out var name) ? name : null ; 10 + } 8 11 }
View fixture on GitHub
# operatorAn expression-bodied operator gets a block with a single return
success
Target symbol M:Shop.Money.op_Addition(Shop.Money,Shop.Money)
Money.cs modified
1 1 namespace Shop ;2 2 3 3 public readonly struct Money 4 4 { 5 5 public Money (decimal amount) => Amount = amount; 6 6 7 7 public decimal Amount { get ; } 8 8 9 − public static Money operator +(Money left, Money right) => new Money (left.Amount + right.Amount ); 9 + public static Money operator +(Money left, Money right) 10 + { 11 + return new Money (left.Amount + right.Amount ); 12 + } 10 13 }
View fixture on GitHub
# read-only-propertyAn expression-bodied property becomes a property with a get accessor
success
Target symbol P:Sample.Name
Sample.cs modified
1 1 public class Sample 2 2 { 3 3 private string _first = "" ; 4 4 private string _last = "" ; 5 5 6 − public string Name => _first + " " + _last; 6 + public string Name 7 + { 8 + get 9 + { 10 + return _first + " " + _last; 11 + } 12 + } 7 13 }
View fixture on GitHub
# return-statementAn expression-bodied method returning a value gets a block with a single return
success
Target symbol M:Sample.Total
Sample.cs modified
1 1 public class Sample 2 2 { 3 3 private int _a; 4 4 private int _b; 5 5 6 − public int Total () => _a + _b; 6 + public int Total () 7 + { 8 + return _a + _b; 9 + } 7 10 }
View fixture on GitHub
# throw-expressionA throw expression becomes a throw statement
success
Target symbol M:Sample.Next
Sample.cs modified
1 1 using System ;2 2 3 3 public class Sample 4 4 { 5 − public int Next () => throw new NotSupportedException (); 5 + public int Next () 6 + { 7 + throw new NotSupportedException (); 8 + } 6 9 }
View fixture on GitHub
# void-methodAn expression-bodied void method gets a block with an expression statement
success
Target symbol M:Sample.Log(System.String)
Sample.cs modified
1 1 using System ;2 2 3 3 public class Sample 4 4 { 5 − public void Log (string message) => Console .WriteLine (message); 5 + public void Log (string message) 6 + { 7 + Console .WriteLine (message); 8 + } 6 9 }
View fixture on GitHub