Замена всех использований метода (Intrece Indirection) - PullRequest
2 голосов
/ 13 мая 2009

Мне вообще не очень нравятся инструменты рефакторинга. Не нужно вдаваться в подробности. Тем не менее, я иногда пробую новые версии. Вот что я пытался сделать при оценке resharper 4.5:

Мне нужно было заменить все методы использования метода-оболочки (который будет создан), но я не смог. Я обычно отстой, замечая очевидную особенность, так ли это? Если у resharper нет этой функции, знаете ли вы такие инструменты?

Редактировать 2: пример был улучшен, чтобы включить вызовы метода экземпляра. Редактировать: Вот простой пример для игры.

    static void Main(string[] args)
    {
        while(true)
        {
            if (Console.ReadKey().Key == ConsoleKey.Escape)
            {
                Thread.Sleep(10);
                if (Quiting()) break;
            }
            Console.Beep(250, 50);
        }
    }

    static bool Quiting()
    {
        if (Console.In.Peek() > 0)
        {
            Console.Beep(250, 150);
            return false;
        }
        return true;
    }

Мне нужно что-то вроде: (Edit2: добавлен пример экземпляра)

    private static StringBuilder _builder = new StringBuilder();

    static void Main(string[] args)
    {
        while(true)
        {
            var key = Console.ReadKey();
            if (key.Key == ConsoleKey.Escape)
            {
                Thread.Sleep(10);
                if (Quiting()) break;
            }
            _builder.Append(" (").Append(key.KeyChar).Append(") ");
            Beep(250, 50);
        }
    }

    static bool Quiting()
    {
        if (Console.In.Peek() > 0)
        {
            Beep(250, 150);
            _builder.Append('@');
            return false;
        }
        return true;
    }

    static void Beep(int frequency, int duration)
    {
        // finally cursor ends up here
        Console.Beep(250, 50);
    }

Console.Beep звонки рефакторинг. Далее позволяет рефакторинг StringBuilder.Append (char):

class Program
{
    private static StringBuilder _builder = new StringBuilder();

    static void Main(string[] args)
    {
        while(true)
        {
            var key = Console.ReadKey();
            if (key.Key == ConsoleKey.Escape)
            {
                Thread.Sleep(10);
                if (Quiting()) break;
            }
            _builder.Append(" (").AppendUpper(key.KeyChar).Append(") ");
            Beep(250, 50);
        }
    }

    static bool Quiting()
    {
        if (Console.In.Peek() > 0)
        {
            Beep(250, 150);
            _builder.AppendUpper('n');
            return false;
        }
        return true;
    }

    static void Beep(int frequency, int duration)
    {
        // finally cursor ends up here
        Console.Beep(250, 50);
    }
}

static class StringBuilderExtensions
{
    public static StringBuilder AppendUpper(this StringBuilder builder, char c)
    {
        return builder.Append(char.ToUpper(c));
    }
}

Выбор из использования и, возможно, пропуск общих параметров (таких как 250 выше) или общих параметров экземпляра для статики без расширения сделает эту функцию более ценной. Надеюсь, это проясняет вопрос.

Ответы [ 4 ]

5 голосов
/ 13 мая 2009

ReSharper не имеет этого как отдельный рефакторинг. Я мог бы сделать это следующим образом:

  1. Выберите содержимое метода для переноса и используйте метод Extract для создания нового частного метода из содержимого.
  2. Оригинальный метод теперь является тривиальной оберткой вокруг «самого себя». Переименуйте его, если хотите, или манипулируйте им по своему усмотрению (сделайте его статичным, перейдите в другой класс, окружите его попыткой / ловлей, чем угодно).

EDIT: Судя по вашим изменениям, у вас возникла дополнительная проблема. Console.Beep не только не в том же классе, но даже не в вашем классе.

Но если вы не возражаете против небольшого поиска и замены, то можете поместить его в свой собственный класс, а затем приступить к рефакторингу:

namespace Temporary {
    public class Console {
        public static void Beep(int x, int y) {System.Console.Beep(x,y);}
    }
}

Затем выполните «Заменить в файлах», чтобы заменить Console.Beep на Temporary.Console.Beep, и действуйте, как указано выше.

4 голосов
/ 13 мая 2009

Он не включен ни в один рефакторинг .NET IIRC, инструмент, который имеет такой рефакторинг, - Eclipse, но не для .NET / C #

3 голосов
/ 13 мая 2009

Предполагая, что метод оболочки будет в том же классе, вы можете переименовать текущий метод в имя нового метода оболочки (ctrl + R + R в Resharper). Это также переименует все вызовы этого метода в решении. Затем вручную переименуйте исходный метод (не используйте Resharper, иначе все вызовы тоже будут переименованы) и добавьте метод-обертку.


Основываясь на ваших изменениях, я думаю, вам не повезет, если вы получите функциональность, которую вы хотите от любой надстройки Visual Studio, которую я видел (кроме простого поиска и замены, который поможет вам в этом. Я думаю).

В зависимости от того, сколько времени и усилий вы готовы посвятить этому, я могу представить, что можно использовать фреймворк DXCore и написать плагин, который будет выполнять этот вид рефакторинга.

0 голосов
/ 21 января 2014

Resharper имеет функцию Поиск и замена на шаблон . Он может искать и заменять шаблоны и выражения.

Это реорганизовало бы все вызовы Console.Beep() для вашего собственного метода. Он заменяет использование только в том случае, если 250 является первым параметром:

Reaplace call to Console.Beep()

Однако это заменит использование Console.Beep() в вашем собственном методе Beep. Вам придется вручную заменить это одно использование.

...