Почему ReSharper жалуется, когда метод может стать статическим, но не стал?
Это потому, что создается только один экземпляр статического метода (по типу) и, таким образом, экономится производительность?
Почему ReSharper жалуется, когда метод может стать статическим, но не стал?
Это потому, что создается только один экземпляр статического метода (по типу) и, таким образом, экономится производительность?
Я считаю этот комментарий очень полезным, поскольку он указывает на две важные вещи:
Это заставляет меня задаться вопросом, действительно ли рассматриваемый метод должен быть частью типа или нет. Поскольку он не использует никаких данных экземпляра, вы должны хотя бы подумать, можно ли его переместить в свой собственный тип. Является ли это неотъемлемой частью типа или действительно служебным методом общего назначения?
Если имеет смысл сохранить метод для определенного типа, есть потенциальный выигрыш в производительности, поскольку компилятор выдаст другой код для статического метода.
Из документации FxCop для того же предупреждения (выделено мной):
«Члены, которые не имеют доступа к данным экземпляра или вызывают методы экземпляра, могут быть помечены как статические (общие в Visual Basic). После того, как вы отметите методы как статические, компилятор будет передавать этим членам невиртуальные сайты вызовов. Испускание невиртуального вызова сайты будут предотвращать проверку во время выполнения для каждого вызова, который гарантирует, что текущий указатель объекта не равен нулю. Это может привести к измеримому увеличению производительности для кода, чувствительного к производительности. В некоторых случаях невозможность доступа к текущему объекту экземпляр представляет собой проблему с правильностью. "
Здесь очень хорошие дебаты по этому вопросу (SO) . Я нахожусь в лагере «если-это-можно-сделать-статичным-сделать-статичным». Я считаю, что это связано с тем, что нужно иметь метод экземпляра, который не использует никаких данных экземпляра. Действительно ли это метод экземпляра в этом случае или это действительно метод класса?
Для использования метода не требуется создавать (ноль) экземпляров класса, если он объявлен как статический ..., что экономит циклы ЦП, необходимые для обработки конструкции, пространство кучи и циклы ЦП сборщиком мусора при извлечении объекта из куча ...
Также ваш вопрос, как это написано
«... создается только один экземпляр статического метода (по типу) ...»
подразумевает, что для метода экземпляра код метода повторяется для каждого экземпляра создаваемого класса. Это неправда. Независимо от того, сколько экземпляров вы создаете для любого типа, код методов загружается в память только один раз. Объект, хранящийся в куче для каждого экземпляра, хранит только «Состояние» типа (нестатические поля и несколько разных переменных отслеживания).
Это не жалоба, это просто совет.
Вам не нужно помещать "this" в стек функции для статического метода. Это еще одна причина, по которой он дешевле.
Для меня наибольшая польза от этого совета ReSharper (вы можете установить его как предупреждение, предложение или подсказку). Это побуждает меня делать как можно больше методов статическими. Это хорошая вещь, поскольку статический метод не имеет прямой зависимости от класса, членом которого он является. Это означает, что его можно легко переместить в другой класс как статический член.
Еще один изящный трюк со статикой в ReSharper - сделать набор связанных методов статическим с помощью рефакторинга «Сделать метод статическим». Это переместит некоторые зависимости в параметры метода. Когда вы позже посмотрите на этот набор методов, вы можете обнаружить, что все они обращаются к определенному объекту определенного типа. Затем вы можете использовать рефакторинг «Сделать метод нестатическим» и указать этот объект как новый указатель 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;
}
}
Статический объект создается при первом использовании и остается в памяти. Если он больше не будет использоваться, это может быть проблемой. Статику сложнее проверить (шутка и т. Д.).