Статический и нестатический метод

Предположим, у вас есть какой-то метод, который можно сделать статическим внутри нестатического класса.
Например:

private double power(double a, double b)
    {
        return (Math.Pow(a, b));
    }

Видите ли вы какую-либо выгоду от изменения сигнатуры метода на статическую? В приведенном выше примере:

private static double power(double a, double b)
    {
        return (Math.Pow(a, b));
    }

Даже если есть некоторая производительность или увеличение памяти, не сделает ли компилятор это простой оптимизацией во время компиляции?


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

10 ответов

Решение

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

Как определено, power не имеет состояния и не имеет побочных эффектов для любого включающего класса, поэтому он должен быть объявлен static,

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

Должно быть небольшое улучшение производительности, если вы объявите метод статическим, потому что компилятор выдаст call Инструкция IL вместо callvirt,

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

Видите ли вы какую-либо выгоду от изменения сигнатуры метода на статическую?

Три преимущества:

  1. Создание статических методов без сохранения состояния помогает документировать и уточнить их назначение. Иначе можно волноваться, от какого загадочного состояния зависит метод?

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

  3. Вызовы статических методов имеют меньшие издержки времени выполнения, чем экземпляры экземпляра. Компилятор не может сделать это преобразование автоматически - одна из причин этого заключается в том, что это повлияет на использование null. Вызов метода по нулевой ссылке необходим для сбоя с исключением NullReferenceException, даже если в методе не используется состояние экземпляра.

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

Для меня простой вопрос: "Должен ли я создавать экземпляр этого объекта просто для вызова этой функции". В случае с вашей функцией я бы сказал, что ответ отрицательный, поэтому он должен быть статичным. Этот метод, кажется, не связан с вашим объектом, поэтому я снова голосую за статические.

Компилятор, вероятно, рассмотрит это в качестве встроенного кода, когда он "JIT" код, поскольку он настолько короткий, и если он это сделает, то, вероятно, сможет оптимизировать любую ссылку на неиспользуемый параметр this. Но вы не можете полагаться ни на что из этого.

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

Этот метод должен быть статическим, потому что он не связан с вашим классом или членом классов. он просто работает со входами в эту функцию.

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


Преимущества статического метода:

Нет необходимости сначала создавать объект. Метод доступен сразу.

Это хорошо, когда у вас есть общие функциональные возможности, которые не зависят от состояния конкретного объекта. Например, посмотрите на класс Arrays или класс Collections из java.util.

Статические методы могут быть полезны для заводов. Передайте ваши требования в качестве параметров, верните совершенно новый объект. Не конструктор в поле зрения.

Недостатки статического метода:

У вас нет экземпляра объекта, поэтому у вас есть доступ только к статическим элементам и вашим собственным локальным переменным. Если вы хотите экземпляр, вы, вероятно, должны создать его самостоятельно.

Вы можете создавать подклассы, но статический метод не может быть абстрактным, поэтому сложнее отделить вашу реализацию от вызывающей стороны.


(PS: я не думаю, что компилятор будет оптимизировать, если он будет статическим или нет.. но не уверен)

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

Я надеюсь, что нам нужно определить разницу между статическим и нестатическим методом. Здесь я публикую несколько простых строк кода, чтобы визуализировать концептуальные различия.

public class StaticVsNonStatic
{
     public string NonStaticMethod() //non-static
     {

         return "I am the Non-Static Method"; 

     }

     static public string StaticMethod() //static
     {

         return "I am Static Method";
     }

 }

Теперь давайте создадим страницу aspx и попытаемся получить доступ к этим двум методам, определенным в классе.

 public partial class StaticVsNonStatic_StaticVsNonWorkplace : System.Web.UI.Page
 {
     protected void Page_Load(object sender, EventArgs e)
     {

        StaticVsNonStatic objStaticVsNonStatic = new StaticVsNonStatic();
        lblDisplayNS.Text = objStaticVsNonStatic.NonStaticMethod(); //Non Static 
        lblDisplayS.Text =  StaticVsNonStatic.StaticMethod();  //Static and called without object
     }
 }

Спасибо и, пожалуйста, оставьте свои комментарии.

С наилучшими пожеланиями, Притом Нанди [Бангладеш]

Другие вопросы по тегам