ReSharper жалуется, когда метод может быть статическим, но не - PullRequest
65 голосов
/ 26 апреля 2009

Почему ReSharper жалуется, когда метод может стать статичным, но это не так?

Это потому, что создается только один экземпляр статического метода (для типа) и, следовательно, экономится на производительности?

Ответы [ 8 ]

101 голосов
/ 26 апреля 2009

Я считаю этот комментарий очень полезным, поскольку он указывает на две важные вещи:

  1. Это заставляет меня спросить себя, если метод вопрос должен быть частью типа или нет. Поскольку он не использует любые данные экземпляра, вы должны в хотя бы подумайте, можно ли его переместить в своем роде. Это неотъемлемая часть типа, или это действительно общее метод полезности цели?

  2. Если есть смысл сохранить метод на конкретный тип, есть потенциальный прирост производительности как компилятор будет выдавать другой код для статического метода.

25 голосов
/ 26 апреля 2009

Из документации FxCop для того же предупреждения (выделение добавлено):

"Члены, которые не обращаются к данным экземпляра или методам экземпляра вызова, могут быть помечены как статические (Shared в Visual Basic). После того, как вы пометите методы как статические, компилятор будет отправлять не виртуальные сайты вызовов этим членам. - виртуальные сайты вызовов будут препятствовать проверке во время выполнения для каждого вызова, которая гарантирует, что текущий указатель объекта не равен нулю. Это может привести к ощутимому увеличению производительности для чувствительного к производительности кода. В некоторых случаях невозможность доступа текущий экземпляр объекта представляет проблему правильности."

6 голосов
/ 27 апреля 2009

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

5 голосов
/ 26 апреля 2009

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

Также ваш вопрос, как оно написано

"... создан только один экземпляр статического метода (для типа) ..."

подразумевает, что для метода экземпляра код метода повторяется для каждого экземпляра создаваемого класса. Это неправда. Независимо от того, сколько экземпляров вы создаете для любого типа, код для методов загружается в память только один раз. Объект, сохраненный в куче для каждого экземпляра, хранит только «состояние» типа (нестатические поля и несколько переменных отслеживания ошибок).

3 голосов
/ 26 апреля 2009

Это не жалоба, это просто совет.

1 голос
/ 27 апреля 2009

Для меня самое большое преимущество этого совета ReSharper (вы можете установить его как предупреждение, предложение или подсказку). Это побуждает меня сделать как можно больше статических методов. Это хорошо, так как статический метод не имеет прямой зависимости от класса, членом которого он является. Это означает, что его можно легко переместить в другой класс в качестве статического члена.

Еще один полезный трюк со статикой в ​​ReSharper - сделать набор связанных методов статическим с помощью рефакторинга «Make Method Static». Это переместит некоторые зависимости в параметры метода. Когда вы посмотрите на этот набор методов позже, вы можете обнаружить, что все они обращаются к определенному объекту определенного типа. Затем вы можете использовать рефакторинг «Make method non-static» и указать этот объект как новый указатель this . Это переместит ваш метод в другой класс.

Из этого:

internal class ClassA
{
    public ClassB Property { get; set; }

    public int Method()
    {
        var classB = Property;
        return classB.Property1 + classB.Property2;
    }
}

internal class ClassB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

к этому:

    public static int Method(ClassB property)
    {
        var classB = property;
        return classB.Property1 + classB.Property2;
    }

к этому:

internal class ClassA
{
    public ClassB Property { get; set; }
}

internal class ClassB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }

    public int Method()
    {
        return Property1 + Property2;
    }
}
1 голос
/ 26 апреля 2009

Вам не нужно помещать «this» в стек функции для статического метода. Это еще одна причина, почему она дешевле.

0 голосов
/ 10 февраля 2015

Статика создается при первом использовании и остается в памяти. Если он больше не будет использоваться, это может быть проблемой. Статические испытания сложнее (moke и т. Д.).

...