2010-09-13 2 views
11

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

Скажем, у меня есть этот класс:

public class SomeClass 
{ 
    public int AProperty { get; set; } 

    public void SomeMethod() 
    { 
     DoStuff(AProperty); 
    } 
} 

Есть ли какие-либо преимущества делают это:

public class SomeClass 
{ 
    public int AProperty { get; set; } 

    public static void SomeMethod(int arg) 
    { 
     DoStuff(arg); 
    } 
} 

Единственное преимущество, что очевидно является то, что теперь я могу получить доступ к SomeMethod непосредственно.

Так ли это хорошая практика, чтобы сделать такие методы статичными, где небольшой рефакторинг позволит или это пустая трата моего времени?

EDIT: Я забыл упомянуть (и комментарий SHELLSHOCK напомнил мне), что причина, я спрашиваю, что я использую ReSharper и это всегда делает предположение, что «Метод X можно сделать статическим» и так далее ...

+0

Возможный дубликат [Статический или нестатический метод] (http://stackoverflow.com/questions/1184701/static-vs-non-static-method) –

+0

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

+0

Я знаю полдня, но я спрашиваю - должен ли я? – Nobody

ответ

15

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

Статический может быть очень выгодным. Как указывает the accepted answer here, статические могут иметь возможность улучшения скорости.

Как правило, если метод не используется и поля класса, то его хорошее время для оценки его функции, однако в конечном итоге полезные методы, которые могут быть вызваны без создания экземпляра объекта, могут быть полезны. Например, классы DirectoryInformation и FileInformation содержат полезные статические методы.

Редактировать

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

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

1

Номер Static is evil. Он плотно соединяет вызывающего абонента с используемым классом и makes it hard to test.

+1

Инструмент анализа кода Microsoft всегда предлагает, чтобы я делал методы статическими, если нет зависимостей между экземплярами. Это плохой совет? – Polyfun

+0

@ShellShock может быть. Если у вас много таких методов, вы, вероятно, нарушаете принципы ООП. Метод объекта должен (почти) всегда работать с данными, связанными с объектом. –

+0

@dark_charlie: Так что вы говорите, что если вы можете использовать метод как статический, вы должны реструктурировать его вместо статического класса? Что делать, если метод логически связан с классом, но технически не использует каких-либо членов? – awe

1

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

Для примера предположим, что у вас есть класс строк и две строки A и B. Для сравнения A и B вы можете использовать метод A.CompareTo (B) или String.Compare (A, B).

Пожалуйста, исправьте меня, если я ошибаюсь.

+0

Я думаю, что «XDocument.Parse» станет лучшим примером. Не было бы особого смысла в создании XDocument просто для использования его метода синтаксического анализа для создания нужного XDocument. –

2

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

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

2

Я попытаюсь ответить на ваш конкретный вопрос, связанный с примером кода, который вы предоставили.

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

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

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

Для (очень простой), например, когда статический является злом, но могут быть преобразованы в не злой версии, представьте себе функцию, которая вычисляет чей-то возраст:

static TimeSpan CalcAge(DateTime dob) { return DateTime.Now - dob; } 

Это проверяемым? Ответ - нет. Он опирается на массово изменчивое статическое состояние, которое составляет DateTime.Now. Вам не гарантируется одинаковый выход для одного и того же входа каждый раз. Для того, чтобы сделать его более дружественным тест:

static TimeSpan CalcAge(DateTime dob, DateTime now) { return now - dob; } 

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

+0

Вы говорите, что если метод полезен только в классе, то не делайте его статичным. Разве это не производительность, полученная путем статического метода? Или еще, что было бы иметь смысл 'private static' метод (который возможен и фактически предложен ReSharper)? – awe

+0

@awe - вы правы, что вызов статических методов должен быть более быстрым. Однако я считаю, что для этого конкретного примера вызов 'someClassInstance.SomeMethod()' лучше, чем 'SomeClass.SomeMethod (someClassInstance.AProperty)'. Я не думаю, что предлагаемый рефактор в вопросе - лучшее, что можно сделать - во многих других случаях это так. Предлагает ли ReSharper этот рефактор для примера выше? Меня это удивило бы, если бы этот метод получил доступ к свойству экземпляра. Вы могли бы отправиться на целый боров и написать «static SomeMethod (SomeClass this)» для * all * ваши методы не виртуального экземпляра, если хотите. –

+0

Я согласен с вами в этом случае, но вы сформулировали его так, как мне было непонятно. Я имею в виду пример, когда метод полезен только в контексте класса, но технически не использует ни одного из членов класса. Этот метод действительно представляет собой лишь некоторую функцию полезности, но никакой другой код, кроме класса, не нуждается в этой функции. Resharper предлагает рефакторинг, если ваш метод не использует каких-либо нестатических членов или методов в вашем классе. Я заметил это в приватном методе, который я создал, чтобы ReSharper предложил сделать статичным. – awe

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