Makes a parameter optional by giving it a default value, and optionally drops the arguments that pass that same value.
Arguments
Argument Meaning parameterthe name of the parameter valuethe default, a C# constant expression removeFromCallSiteswhen true, drop arguments that pass the default; false if left out
The target is the method or constructor, by symbol.
Precondition
The parameter has no default yet. Changing an existing default would change what calls that leave it out pass. It is not ref, out, in, params or the this of an extension method. Every parameter after it is optional or a params array. The value is a compile-time constant the parameter's type can take. Every member of the method's family is declared in the solution. The result compiles.
The parameter gets = value on the method and on every override, interface member and implementation related to it, so a call through any of them sees the same default. With removeFromCallSites, every argument whose constant value equals the default is dropped, whether positional or named. When a dropped argument is followed by another, the one after it is named.
Preserved
What every call passes: a dropped argument passed the default. A comment after the parameter's name stays after the default.
Limitations
Only arguments that are constants are compared with the default; a variable that happens to hold the default is kept. Numbers of different types count as equal when their values are, which is what they become once converted to the parameter's type.
Error codes
Code Meaning already-optionalthe parameter already has a default ref-or-out-parameterthe parameter is ref, out, in, params or this later-parameter-requireda parameter after it has no default not-constantthe value is not a compile-time constant incompatible-valuethe value cannot be converted to the parameter's type
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.
# already-optional-rejectedRefuses a parameter that already has a default, since changing it would change what calls that leave it out pass
refusal
Target symbol M:Shop.Money.Format(System.Decimal,System.String)
Arguments parameter"currency"value"\"EUR\""
Refuses already-optional; every file is left unchanged
Money.cs input
1 namespace Shop ;2 3 public class Money 4 { 5 public string Format (decimal amount, string currency = "GBP" ) 6 { 7 return amount + " " + currency; 8 } 9 }
View fixture on GitHub
# before-optional-parameterGives a default to a parameter followed by an optional one; a call that drops the argument names the one after it
success
Target symbol M:Shop.Printer.Print(System.String,System.Int32,System.Boolean)
Arguments parameter"copies"value"1"removeFromCallSitestrue
Printer.cs modified
1 1 namespace Shop ;2 2 3 3 public class Printer 4 4 { 5 − public string Print (string text, int copies, bool colour = false ) 5 + public string Print (string text, int copies = 1 , bool colour = false ) 6 6 { 7 7 return text + copies + colour; 8 8 } 9 9 10 10 public string Run () 11 11 { 12 − return Print ("a" , 1 , true ) + Print ("b" , 1 ) + Print ("c" , 2 ); 12 + return Print ("a" , colour: true ) + Print ("b" ) + Print ("c" , 2 ); 13 13 } 14 14 }
View fixture on GitHub
# drop-matching-argumentsGives a parameter a default and drops the arguments that pass the same value, in another file and by name
success
Target symbol M:Shop.Catalogue.Page(System.Int32,System.Int32)
Arguments parameter"size"value"20"removeFromCallSitestrue
Browser.cs modified
1 1 namespace Shop ;2 2 3 3 public class Browser 4 4 { 5 5 public string Show (Catalogue catalogue) 6 6 { 7 − return catalogue.Page (1 , 20 ) + catalogue.Page (2 , 50 ) + catalogue.Page (3 , size: 20 ); 7 + return catalogue.Page (1 ) + catalogue.Page (2 , 50 ) + catalogue.Page (3 ); 8 8 } 9 9 }
Catalogue.cs modified
1 1 namespace Shop ;2 2 3 3 public class Catalogue 4 4 { 5 − public string Page (int number, int size) 5 + public string Page (int number, int size = 20 ) 6 6 { 7 7 return number + "/" + size; 8 8 } 9 9 }
View fixture on GitHub
# incompatible-value-rejectedRefuses a default of a type the parameter cannot take
refusal
Target symbol M:Shop.Money.Format(System.Decimal,System.String)
Arguments parameter"currency"value"42"
Refuses incompatible-value; every file is left unchanged
Money.cs input
1 namespace Shop ;2 3 public class Money 4 { 5 public string Format (decimal amount, string currency) 6 { 7 return amount + " " + currency; 8 } 9 }
View fixture on GitHub
# interface-and-implementationGives the parameter the same default on the interface and its implementation, so calls through either may leave it out
success
Target symbol M:Shop.IClock.Stamp(System.Int32,System.String)
Arguments parameter"pattern"value"\"t\""removeFromCallSitestrue
Clock.cs modified
1 1 namespace Shop ;2 2 3 3 public interface IClock 4 4 { 5 − string Stamp (int hour, string pattern); 5 + string Stamp (int hour, string pattern = "t" ); 6 6 } 7 7 8 8 public class FixedClock : IClock 9 9 { 10 − public string Stamp (int hour, string pattern) 10 + public string Stamp (int hour, string pattern = "t" ) 11 11 { 12 12 return hour + pattern; 13 13 } 14 14 } 15 15 16 16 public class Log 17 17 { 18 18 public string Write (IClock clock, FixedClock fixedClock) 19 19 { 20 − return clock.Stamp (9 , "t" ) + fixedClock.Stamp (10 , "t" ); 20 + return clock.Stamp (9 ) + fixedClock.Stamp (10 ); 21 21 } 22 22 }
View fixture on GitHub
# last-parameterGives the last parameter a default, leaving calls as they are
success
Target symbol M:Shop.Money.Format(System.Decimal,System.String)
Arguments parameter"currency"value"\"GBP\""
Money.cs modified
1 1 namespace Shop ;2 2 3 3 public class Money 4 4 { 5 − public string Format (decimal amount, string currency) 5 + public string Format (decimal amount, string currency = "GBP" ) 6 6 { 7 7 return amount + " " + currency; 8 8 } 9 9 10 10 public string Price () 11 11 { 12 12 return Format (9.99m , "GBP" ); 13 13 } 14 14 }
View fixture on GitHub
# later-parameter-required-rejectedRefuses a default on a parameter followed by a required one
refusal
Target symbol M:Shop.Money.Format(System.Decimal,System.String)
Arguments parameter"amount"value"0m"
Refuses later-parameter-required mentioning “currency”; every file is left unchanged
Money.cs input
1 namespace Shop ;2 3 public class Money 4 { 5 public string Format (decimal amount, string currency) 6 { 7 return amount + " " + currency; 8 } 9 }
View fixture on GitHub
# not-constant-rejectedRefuses a default that is not a compile-time constant
refusal
Target symbol M:Shop.Money.Format(System.Decimal,System.String)
Arguments parameter"currency"value"System.Environment.MachineName"
Refuses not-constant; every file is left unchanged
Money.cs input
1 namespace Shop ;2 3 public class Money 4 { 5 public string Format (decimal amount, string currency) 6 { 7 return amount + " " + currency; 8 } 9 }
View fixture on GitHub
# nullable-parameterGives a nullable reference parameter a null default in a nullable context and drops null arguments
success
Target symbol M:Shop.Notes.Add(System.String,System.String)
Arguments parameter"author"value"null"removeFromCallSitestrue
Project nullable enable
Notes.cs modified
1 1 namespace Shop ;2 2 3 3 public class Notes 4 4 { 5 − public string Add (string text, string ? author) 5 + public string Add (string text, string ? author = null ) 6 6 { 7 7 return text + (author ?? "" ); 8 8 } 9 9 10 10 public string Both () 11 11 { 12 − return Add ("first" , null ) + Add ("second" , "sam" ); 12 + return Add ("first" ) + Add ("second" , "sam" ); 13 13 } 14 14 }
View fixture on GitHub
# preserves-triviaA comment after the parameter's name stays after the default
success
Target symbol M:Shop.Grid.Rows(System.Int32,System.Int32)
Arguments parameter"height"value"10"
Grid.cs modified
1 1 namespace Shop ;2 2 3 3 public class Grid 4 4 { 5 5 public int Rows ( 6 6 int width, 7 − int height /* in cells */ ) 7 + int height = 10 /* in cells */ ) 8 8 { 9 9 return width * height; 10 10 } 11 11 }
View fixture on GitHub
# ref-or-out-parameter-rejectedRefuses an out parameter, which cannot have a default
refusal
Target symbol M:Shop.Parser.TryRead(System.String,System.Int32@)
Refuses ref-or-out-parameter; every file is left unchanged
Parser.cs input
1 namespace Shop ;2 3 public class Parser 4 { 5 public bool TryRead (string text, out int value ) 6 { 7 return int .TryParse (text, out value ); 8 } 9 }
View fixture on GitHub