Resharper tip #1: Push code into a method / Pull code out of a method

October 12, 2015 at 2:59 pm

Resharper is a great tool, but many times that operation that I want to perform isn’t possible with a single refactoring; you need multiple refactorings to get the result that you want. I did a search and could find these anywhere, so I thought I’d share them with you.

If you know where more of these things are described and/or you know a better way of doing what I describe, please let me know.

Push code into a method

Consider the following code:

   1: static void Main(string[] args)

   2: {

   3:     DateTime start = DateTime.Now;

   4:  

   5:  

   6:     DateTime oneDayEarlier = start - TimeSpan.FromDays(1);

   7:     string startString = start.ToShortDateString();

   8:  

   9:     Process(oneDayEarlier, startString);

  10:  

  11: }

  12:  

  13: private static void Process(DateTime oneDayEarlier, string startString)

  14: {

  15:     Console.WriteLine(oneDayEarlier);

  16:     Console.WriteLine(startString);

  17: }

Looking at the code in Main(), there are a couple of variables that are passed into the Process() method. A little examination shows that things would be cleaner they were in the Process method, but there’s no “move code into method” refactoring, so I’ll have to synthesize it out of the refactorings that I have. I start by renaming the Process() method to Process2(). Use whatever name you want here:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         DateTime start = DateTime.Now;

   6:  

   7:  

   8:         DateTime oneDayEarlier = start - TimeSpan.FromDays(1);

   9:         string startString = start.ToShortDateString();

  10:  

  11:         Process2(oneDayEarlier, startString);

  12:  

  13:     }

  14:  

  15:     private static void Process2(DateTime oneDayEarlier, string startString)

  16:     {

  17:         Console.WriteLine(oneDayEarlier);

  18:         Console.WriteLine(startString);

  19:     }

  20: }

Next, select the lines that I want to include into the method plus the method call itself, and do an Extract Method refactoring to create a new Process() method:

   1: static void Main(string[] args)

   2: {

   3:     DateTime start = DateTime.Now;

   4:  

   5:  

   6:     Process(start);

   7: }

   8:  

   9: private static void Process(DateTime start)

  10: {

  11:     DateTime oneDayEarlier = start - TimeSpan.FromDays(1);

  12:     string startString = start.ToShortDateString();

  13:  

  14:     Process2(oneDayEarlier, startString);

  15: }

  16:  

  17: private static void Process2(DateTime oneDayEarlier, string startString)

  18: {

  19:     Console.WriteLine(oneDayEarlier);

  20:     Console.WriteLine(startString);

  21: }

Finally, inline the Process2() method:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         DateTime start = DateTime.Now;

   6:  

   7:  

   8:         Process(start);

   9:     }

  10:  

  11:     private static void Process(DateTime start)

  12:     {

  13:         DateTime oneDayEarlier = start - TimeSpan.FromDays(1);

  14:         string startString = start.ToShortDateString();

  15:  

  16:         Console.WriteLine(oneDayEarlier);

  17:         Console.WriteLine(startString);

  18:     }

  19: }

Three quick refactorings got me to where I wanted, and it’s about 15 seconds of work if you use the predefined keys.

Pull Code Out of a Method

Sometimes, I have some code that I want to pull out of a method. Consider the following:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         int n = 15;

   6:  

   7:         WriteInformation("Information: ", n);

   8:     }

   9:  

  10:     private static void WriteInformation(string information, int n)

  11:     {

  12:         File.WriteAllText("information.txt", information + n);

  13:     }

  14: }

I have a few options here. We can pull “information.txt” out easily by selecting it and using Introduce Parameter:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         int n = 15;

   6:  

   7:         WriteInformation("Information: ", n, "information.txt");

   8:     }

   9:  

  10:     private static void WriteInformation(string information, int n, string filename)

  11:     {

  12:         File.WriteAllText(filename, information + n);

  13:     }

  14: }

I could use that same approach to pull out “information + n”, but I’m going to do it an alternate way that works well if I have a chunk of code. First, I introduce a variable:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         int n = 15;

   6:  

   7:         WriteInformation("Information: ", n, "information.txt");

   8:     }

   9:  

  10:     private static void WriteInformation(string information, int n, string filename)

  11:     {

  12:         string contents = information + n;

  13:         File.WriteAllText(filename, contents);

  14:     }

  15: }

I rename the method:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         int n = 15;

   6:  

   7:         WriteInformation2("Information: ", n, "information.txt");

   8:     }

   9:  

  10:     private static void WriteInformation2(string information, int n, string filename)

  11:     {

  12:         string contents = information + n;

  13:         File.WriteAllText(filename, contents);

  14:     }

  15: }

And I now extract the code that I want to remain in the method to a new method:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         int n = 15;

   6:  

   7:         WriteInformation2("Information: ", n, "information.txt");

   8:     }

   9:  

  10:     private static void WriteInformation2(string information, int n, string filename)

  11:     {

  12:         string contents = information + n;

  13:         WriteInformation(filename, contents);

  14:     }

  15:  

  16:     private static void WriteInformation(string filename, string contents)

  17:     {

  18:         File.WriteAllText(filename, contents);

  19:     }

  20: }

And, finally, I inline the original method:

   1: class Program

   2: {

   3:     static void Main(string[] args)

   4:     {

   5:         int n = 15;

   6:  

   7:         string contents = "Information: " + n;

   8:         WriteInformation("information.txt", contents);

   9:     }

  10:  

  11:     private static void WriteInformation(string filename, string contents)

  12:     {

  13:         File.WriteAllText(filename, contents);

  14:     }

  15: }

Tags: