Assigns a field that nothing uses yet from a constructor parameter, at the end of the constructor. Nothing reads the field, so the assignment changes nothing the code does; it prepares the field for a later step, such as Replace Expression with Field in Constructor Injection's recipe.
Target
The constructor, by symbol, with:
Argument Meaning fieldthe field to assign, declared in the constructor's class parameterthe constructor parameter to assign it from
Precondition
The target is an instance constructor with a block or expression body. The constructor has the parameter, and the class declares an instance field of that name. The parameter's type converts implicitly to the field's type. Nothing uses the field: no code in any file reads or writes it, and it has no initializer. The constructor does not return early, so the assignment runs whenever the constructor completes.
field = parameter; is added as the constructor's last statement, before any comment that closes the body. It is written this.field = parameter; where a parameter or local of the constructor has the field's name.An expression-bodied constructor gets a block body holding its expression and then the assignment.
Preserved
Everything the code does: the field was never read, so giving it a value cannot be observed. Comments on the constructor's statements.
Limitations
Reflection that reads the field would see the new value. A field used anywhere is refused, even where the assignment would not change what the uses see; assign it by hand, or use Introduce Field for a new one first.
Error codes
Code Meaning not-a-constructorthe target is not an instance constructor with a body unknown-parameterthe constructor has no parameter of that name unknown-fieldthe class declares no instance field of that name type-mismatchthe field's type cannot hold the parameter field-in-usethe field is read, written or initialised somewhere already returns-earlythe constructor contains a return statement
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.
# assigns-at-endAssigns an unused field from a constructor parameter at the end of the constructor
success
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_mailer"parameter"mailer"
OrderService.cs modified
1 1 using Shop .Mail ;2 2 3 3 namespace Shop 4 4 { 5 5 public class OrderService 6 6 { 7 7 private readonly string _prefix; 8 8 private Mailer _mailer; 9 9 10 10 public OrderService (string prefix, Mailer mailer) 11 11 { 12 12 _prefix = prefix; 13 + _mailer = mailer; 13 14 } 14 15 15 16 public void Place (string order) 16 17 { 17 18 var mailer = new Mailer ("smtp.example.com" ); 18 19 mailer.Send (_prefix + order); 19 20 } 20 21 } 21 22 }
Mailer.cs unchanged
1 1 using System .Collections .Generic ;2 2 3 3 namespace Shop .Mail 4 4 { 5 5 public class Mailer 6 6 { 7 7 private readonly string _host; 8 8 private readonly List <string > _sent = new List <string >(); 9 9 10 10 public Mailer (string host) 11 11 { 12 12 _host = host; 13 13 } 14 14 15 15 public void Send (string message) 16 16 { 17 17 _sent.Add (_host + ": " + message); 18 18 } 19 19 } 20 20 }
View fixture on GitHub
# expression-bodied-constructorAn expression-bodied constructor gets a block body holding its expression and then the assignment
success
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_mailer"parameter"mailer"
OrderService.cs modified
1 1 using Shop .Mail ;2 2 3 3 namespace Shop 4 4 { 5 5 public class OrderService 6 6 { 7 7 private readonly string _prefix; 8 8 private Mailer _mailer; 9 9 10 − public OrderService (string prefix, Mailer mailer) => _prefix = prefix; 10 + public OrderService (string prefix, Mailer mailer) 11 + { 12 + _prefix = prefix; 13 + _mailer = mailer; 14 + } 11 15 12 16 public void Place (string order) 13 17 { 14 18 var mailer = new Mailer ("smtp.example.com" ); 15 19 mailer.Send (_prefix + order); 16 20 } 17 21 } 18 22 }
Mailer.cs unchanged
1 1 using System .Collections .Generic ;2 2 3 3 namespace Shop .Mail 4 4 { 5 5 public class Mailer 6 6 { 7 7 private readonly string _host; 8 8 private readonly List <string > _sent = new List <string >(); 9 9 10 10 public Mailer (string host) 11 11 { 12 12 _host = host; 13 13 } 14 14 15 15 public void Send (string message) 16 16 { 17 17 _sent.Add (_host + ": " + message); 18 18 } 19 19 } 20 20 }
View fixture on GitHub
# field-in-use-rejectedRefuses a field that is already read, whose value the assignment would change
refusal
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_mailer"parameter"mailer"
Refuses field-in-use; every file is left unchanged
Mailer.cs input
1 using System .Collections .Generic ;2 3 namespace Shop .Mail 4 { 5 public class Mailer 6 { 7 private readonly string _host; 8 private readonly List <string > _sent = new List <string >(); 9 10 public Mailer (string host) 11 { 12 _host = host; 13 } 14 15 public void Send (string message) 16 { 17 _sent.Add (_host + ": " + message); 18 } 19 } 20 }
OrderService.cs input
1 using Shop .Mail ;2 3 namespace Shop 4 { 5 public class OrderService 6 { 7 private readonly string _prefix; 8 private Mailer _mailer; 9 10 public OrderService (string prefix, Mailer mailer) 11 { 12 _prefix = prefix; 13 } 14 15 public void Place (string order) 16 { 17 var mailer = _mailer ?? new Mailer ("smtp.example.com" ); 18 mailer.Send (_prefix + order); 19 } 20 } 21 }
View fixture on GitHub
# generic-typeIn a generic class with an empty constructor, a field of the type parameter is assigned from a parameter of that type
success
Target symbol M:Caching.Cache`1.#ctor(`0)
Arguments field"_fallback"parameter"fallback"
Cache.cs modified
1 1 namespace Caching 2 2 { 3 3 public class Cache <T > 4 4 { 5 5 private T _fallback; 6 6 7 7 public Cache (T fallback) 8 8 { 9 + _fallback = fallback; 9 10 } 10 11 } 11 12 }
View fixture on GitHub
# not-a-constructor-rejectedRefuses a method, which runs after construction
refusal
Target symbol M:Shop.OrderService.Place(System.String)
Arguments field"_mailer"parameter"order"
Refuses not-a-constructor; every file is left unchanged
Mailer.cs input
1 using System .Collections .Generic ;2 3 namespace Shop .Mail 4 { 5 public class Mailer 6 { 7 private readonly string _host; 8 private readonly List <string > _sent = new List <string >(); 9 10 public Mailer (string host) 11 { 12 _host = host; 13 } 14 15 public void Send (string message) 16 { 17 _sent.Add (_host + ": " + message); 18 } 19 } 20 }
OrderService.cs input
1 using Shop .Mail ;2 3 namespace Shop 4 { 5 public class OrderService 6 { 7 private readonly string _prefix; 8 private Mailer _mailer; 9 10 public OrderService (string prefix, Mailer mailer) 11 { 12 _prefix = prefix; 13 } 14 15 public void Place (string order) 16 { 17 var mailer = new Mailer ("smtp.example.com" ); 18 mailer.Send (_prefix + order); 19 } 20 } 21 }
View fixture on GitHub
# nullable-fieldWith nullable reference types enabled, a nullable field of an interface type is assigned from a parameter of a class implementing it
success
Target symbol M:Shop.OrderService.#ctor(Shop.Mailer)
Arguments field"_mailer"parameter"mailer"
Project nullable enable
OrderService.cs modified
1 1 namespace Shop 2 2 { 3 3 public interface IMailer 4 4 { 5 5 void Send (string message); 6 6 } 7 7 8 8 public class Mailer : IMailer 9 9 { 10 10 public void Send (string message) 11 11 { 12 12 } 13 13 } 14 14 15 15 public class OrderService 16 16 { 17 17 private IMailer ? _mailer; 18 18 19 19 public OrderService (Mailer mailer) 20 20 { 21 + _mailer = mailer; 21 22 } 22 23 } 23 24 }
View fixture on GitHub
# returns-early-rejectedRefuses a constructor that can return before its end, where the assignment would not run
refusal
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_mailer"parameter"mailer"
Refuses returns-early; every file is left unchanged
Mailer.cs input
1 using System .Collections .Generic ;2 3 namespace Shop .Mail 4 { 5 public class Mailer 6 { 7 private readonly string _host; 8 private readonly List <string > _sent = new List <string >(); 9 10 public Mailer (string host) 11 { 12 _host = host; 13 } 14 15 public void Send (string message) 16 { 17 _sent.Add (_host + ": " + message); 18 } 19 } 20 }
OrderService.cs input
1 using Shop .Mail ;2 3 namespace Shop 4 { 5 public class OrderService 6 { 7 private readonly string _prefix; 8 private Mailer _mailer; 9 10 public OrderService (string prefix, Mailer mailer) 11 { 12 _prefix = prefix; 13 if (prefix.Length == 0 ) 14 return ; 15 _prefix = prefix + "-" ; 16 } 17 18 public void Place (string order) 19 { 20 var mailer = new Mailer ("smtp.example.com" ); 21 mailer.Send (_prefix + order); 22 } 23 } 24 }
View fixture on GitHub
# same-name-as-parameterA field with the parameter's name is assigned through this
success
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"mailer"parameter"mailer"
OrderService.cs modified
1 1 using Shop .Mail ;2 2 3 3 namespace Shop 4 4 { 5 5 public class OrderService 6 6 { 7 7 private readonly string _prefix; 8 8 private Mailer mailer; 9 9 10 10 public OrderService (string prefix, Mailer mailer) 11 11 { 12 12 _prefix = prefix; 13 + this .mailer = mailer; 13 14 } 14 15 15 16 public void Place (string order) 16 17 { 17 18 var mailer = new Mailer ("smtp.example.com" ); 18 19 mailer.Send (_prefix + order); 19 20 } 20 21 } 21 22 }
Mailer.cs unchanged
1 1 using System .Collections .Generic ;2 2 3 3 namespace Shop .Mail 4 4 { 5 5 public class Mailer 6 6 { 7 7 private readonly string _host; 8 8 private readonly List <string > _sent = new List <string >(); 9 9 10 10 public Mailer (string host) 11 11 { 12 12 _host = host; 13 13 } 14 14 15 15 public void Send (string message) 16 16 { 17 17 _sent.Add (_host + ": " + message); 18 18 } 19 19 } 20 20 }
View fixture on GitHub
# type-mismatch-rejectedRefuses a field whose type cannot hold the parameter
refusal
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_prefix"parameter"mailer"
Refuses type-mismatch; every file is left unchanged
Mailer.cs input
1 using System .Collections .Generic ;2 3 namespace Shop .Mail 4 { 5 public class Mailer 6 { 7 private readonly string _host; 8 private readonly List <string > _sent = new List <string >(); 9 10 public Mailer (string host) 11 { 12 _host = host; 13 } 14 15 public void Send (string message) 16 { 17 _sent.Add (_host + ": " + message); 18 } 19 } 20 }
OrderService.cs input
1 using Shop .Mail ;2 3 namespace Shop 4 { 5 public class OrderService 6 { 7 private readonly string _prefix; 8 private Mailer _mailer; 9 10 public OrderService (string prefix, Mailer mailer) 11 { 12 _prefix = prefix; 13 } 14 15 public void Place (string order) 16 { 17 var mailer = new Mailer ("smtp.example.com" ); 18 mailer.Send (_prefix + order); 19 } 20 } 21 }
View fixture on GitHub
# unknown-field-rejectedRefuses a field the class does not declare
refusal
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_sender"parameter"mailer"
Refuses unknown-field mentioning “'_sender'”; every file is left unchanged
Mailer.cs input
1 using System .Collections .Generic ;2 3 namespace Shop .Mail 4 { 5 public class Mailer 6 { 7 private readonly string _host; 8 private readonly List <string > _sent = new List <string >(); 9 10 public Mailer (string host) 11 { 12 _host = host; 13 } 14 15 public void Send (string message) 16 { 17 _sent.Add (_host + ": " + message); 18 } 19 } 20 }
OrderService.cs input
1 using Shop .Mail ;2 3 namespace Shop 4 { 5 public class OrderService 6 { 7 private readonly string _prefix; 8 private Mailer _mailer; 9 10 public OrderService (string prefix, Mailer mailer) 11 { 12 _prefix = prefix; 13 } 14 15 public void Place (string order) 16 { 17 var mailer = new Mailer ("smtp.example.com" ); 18 mailer.Send (_prefix + order); 19 } 20 } 21 }
View fixture on GitHub
# unknown-parameter-rejectedRefuses a parameter the constructor does not have
refusal
Target symbol M:Shop.OrderService.#ctor(System.String,Shop.Mail.Mailer)
Arguments field"_mailer"parameter"sender"
Refuses unknown-parameter mentioning “'sender'”; every file is left unchanged
Mailer.cs input
1 using System .Collections .Generic ;2 3 namespace Shop .Mail 4 { 5 public class Mailer 6 { 7 private readonly string _host; 8 private readonly List <string > _sent = new List <string >(); 9 10 public Mailer (string host) 11 { 12 _host = host; 13 } 14 15 public void Send (string message) 16 { 17 _sent.Add (_host + ": " + message); 18 } 19 } 20 }
OrderService.cs input
1 using Shop .Mail ;2 3 namespace Shop 4 { 5 public class OrderService 6 { 7 private readonly string _prefix; 8 private Mailer _mailer; 9 10 public OrderService (string prefix, Mailer mailer) 11 { 12 _prefix = prefix; 13 } 14 15 public void Place (string order) 16 { 17 var mailer = new Mailer ("smtp.example.com" ); 18 mailer.Send (_prefix + order); 19 } 20 } 21 }
View fixture on GitHub