2009-07-26 5 views
29

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

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)); 
    } 

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


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

+0

@ Всем, я знаю, что это «древний» вопрос в годы развития, но он по-прежнему актуальен сегодня. Многие ** превосходные ** ответы ниже. Нужны фактические показатели производительности для вашего конкретного сценария? Напишите краткую программу, которая вызывает метод достаточно раз (между «var start = DateTime.Now()» и «var end = DateTime.Now()»), чтобы иметь прошедший период, достаточно большой для сравнения. Запустите его несколько раз с помощью 'static' и несколько раз без' static' и сравните разницу. Может быть, открыть TaskManager и наблюдать за использованием памяти для каждого сценария. –

+0

Просто для полноты, вместо сравнения разницы между двумя 'DateTime.Now()', используйте класс '' StopWatch' '(https://msdn.microsoft.com/en-us/library/system.diagnostics. секундомер (v = vs.110) .aspx). EDIT - Почему? Это более точная и удобная в использовании функция 'DateTime.Now()'. –

ответ

7

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

+0

Хорошая точка. Я не думал об этом, спасибо. – Elad

1

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

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


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

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

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

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

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

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

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


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

33

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

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

+0

Где ссылка? –

+0

@niko: исправлено. Извините и спасибо. – jason

+0

+1 для ссылки msdn. –

2

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

+0

@Cody C: Но как можно ответить на вопрос «Должен ли я создать экземпляр этого объекта, чтобы вызвать эту функцию?»? – jason

+1

IMO это вопрос «Нужен ли мне объект с состоянием, если я хочу использовать эту функцию?» Если я просто создаю объект, чтобы выполнить простую функцию, тогда ответ обычно отсутствует. –

+1

Этот пример является «частным», поэтому в данном случае это не будет рассматриваться (это было бы только в том случае, если оно было «публичным»). В этом случае единственное соображение - это вопросы, связанные с производительностью. – awe

8

Должно быть небольшое улучшение производительности, если вы объявите метод static, потому что компилятор будет генерировать команду ILL вместо callvirt.

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

0

Я считаю, что компилятор не будет оптимизировать это в статический метод. Существует усиление производительности, так как указатель не нужно проверять, будет ли он равен нулю во время выполнения. Посмотрите на FXCop rule для справки.

1

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

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

+0

У вас уже есть объект ('this'), как пример для метода' private'. – awe

-5

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

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 
    } 
} 

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

С наилучшими пожеланиями, Pritom Nandy [Бангладеш]

+2

Elad явно уже знает, как вызвать статический метод. Поскольку вы только начинаете отвечать на вопросы на этом сайте, я бы предложил искать вопросы, которые еще не получили принятого ответа. Вы можете сказать, что при поиске вопросов количество ответов будет желтым, если есть принятый ответ и белый, если нет. Есть красный фон, если никто еще не пытался ответить на вопрос, на что лучше всего смотреть. Добро пожаловать в stackoverflow :) –

2

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

3

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

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

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

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

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

Смежные вопросы