.NET Tools
Essential productivity kit for .NET and game developers
ReSharper’s Extract Method refactoring with better C# 6 and C# 7 support
If you are using the latest ReSharper 2017.3 EAP build, you may have noticed a few changes in the Extract Method refactoring, which now comes with better support for C# 6 and C# 7. Support for local functions has been added, there’s now an option to return value tuple instead of out
parameters, and Extract Method now works in expression-bodied members. Let’s see!
Extract to local function
Starting with C# 7.0 we can make use of local functions – private methods that are nested in another member and that can only be called from their containing member. ReSharper 2017.3’s Extract Method refactoring (Ctrl+R, M) now supports extracting a bit of code into a full method, or into a local function:
When extracting code into a local function, we can specify its scope. We can place it at the beginning (or the end) of the containing member, or just before/after its usage.
If required closures aren’t available at the selected location, they will be converted to parameters. For example, take the following piece of code:
public void Method(string word) { (int index, bool found) = FindWord(word); if (found) { var message = $"Word '{word}' is found at index {index}"; // We will extract the following line into a local function Console.WriteLine(message); } }
If we extract the Console.WriteLine(message);
statement into a local function, ReSharper will generate different code depending on the location we place that function. If we place the generated function at the start of Method()
, the message
closure is not yet available and our local function will require a parameter:
If we place the local function further down in our containing method, the message
closure is available and can be accessed by our local function:
Note that it’s always possible to use parameters instead of closures, by explicitly checking them in the refactoring UI.
Smart extraction of local functions in conflicting code
Local functions are often located at the beginning/end of their containing method (examples in Microsoft’s C# programming guide). This makes it often impossible to extract methods easily, as it would require selecting multiple lines of code at various locations in our code.
ReSharper 2017.3 helps by extracting both the selected line(s) of code as well as the local function that is required by it:
Similarly if it would not be possible to keep the local function in its containing member, ReSharper will extract it into a regular method:
Return value tuple instead of out
parameter
When using C# 7.0 in our code base, the Extract Method refactoring now add a option to return value tuples instead of working with out
parameters. When extracting a method (or local function), we can now choose whether we want to return a single value and assign one or more out
parameters, or return multiple values using a C# 7.0 tuple:
Other C# 6.0 and C# 7.0 improvements
ReSharper 2017.3’s Extract Method refactoring now better handles C# 6.0 and C# 7.0 code features:
- Extract Method is now available from expression-bodied members.
- Conflict resolution for
nameof()
usages. - Better usage of C# 7.0 syntax when rewriting code during method extraction.
- Generation of
out var
at the call site, as well as removingreadonly
from properties if needed.
Depending on the options we select in the Extract Method refactoring UI, ReSharper will use the preferred C# 6.0 or C# 7.0 syntax:
Download ReSharper 2017.3 EAP now and give it a try! We’d love to hear your feedback.