При создании класса, который имеет внутренние частные методы, обычно для уменьшения дублирования кода, которые не требуют использования каких-либо полей экземпляра, есть ли преимущества в производительности или памяти для объявления метода как статического?
Пример:
foreach (XmlElement element in xmlDoc.DocumentElement.SelectNodes("sample"))
{
string first = GetInnerXml(element, ".//first");
string second = GetInnerXml(element, ".//second");
string third = GetInnerXml(element, ".//third");
}
...
private static string GetInnerXml(XmlElement element, string nodeName)
{
return GetInnerXml(element, nodeName, null);
}
private static string GetInnerXml(XmlElement element, string nodeName, string defaultValue)
{
XmlNode node = element.SelectSingleNode(nodeName);
return node == null ? defaultValue : node.InnerXml;
}
Есть ли какое-либо преимущество в объявлении методов GetInnerXml () как статических? Нет мнений, пожалуйста, у меня есть мнение.
c#
performance
NerdFury
источник
источник
Ответы:
Со страницы правил FxCop об этом:
источник
Когда я пишу класс, большинство методов делятся на две категории:
Статические методы полезны, потому что, просто взглянув на его сигнатуру, вы узнаете, что вызывающий его не использует и не изменяет состояние текущего экземпляра.
Возьмите этот пример:
Если экземпляр состояния библиотеки когда-либо облажается, и я пытаюсь выяснить, почему, я могу исключить findBook как виновника, просто по его подписи.
Я стараюсь общаться как можно больше с помощью сигнатуры метода или функции, и это отличный способ сделать это.
источник
Library
есть поле экземпляраList<Book> _books
для хранения его книг (не так, как вы,Library
вероятно, разработали бы класс, но с помощью w / e), и он передает этот списокfindBook
, и что статический метод вызываетbooks.Clear()
илиbooks.Reverse()
и так далее. Если вы предоставляете статическому методу доступ к ссылке на какое-либо изменяемое состояние, то этот статический метод может очень испортить ваше состояние.Вызов статического метода генерирует инструкцию вызова на промежуточном языке Microsoft (MSIL), тогда как вызов метода экземпляра генерирует инструкцию callvirt, которая также проверяет ссылки на нулевые объекты. Тем не менее, в большинстве случаев разница в производительности между ними незначительна.
источник: MSDN - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.110).aspx
источник
Да, компилятору не нужно передавать неявный
this
указатель наstatic
методы. Даже если вы не используете его в своем методе экземпляра, он все еще передается.источник
Это будет немного быстрее, поскольку этот параметр не передается (хотя затраты на вызов метода, вероятно, значительно больше, чем экономия).
Я бы сказал, что лучшая причина, которую я могу придумать для частных статических методов, заключается в том, что это означает, что вы не можете случайно изменить объект (так как указатель отсутствует).
источник
Это заставляет вас не забывать также объявлять любые члены в области классов, которые функция также использует как статические, что должно сохранить память для создания этих элементов для каждого экземпляра.
источник
Я очень предпочитаю, чтобы все частные методы были статическими, если они действительно не могут быть. Я бы предпочел следующее:
по каждому методу, получающему доступ к полю экземпляра. Почему это? Поскольку, поскольку этот процесс вычисления становится более сложным, и класс заканчивается 15-ю закрытыми вспомогательными методами, я ДЕЙСТВИТЕЛЬНО хочу иметь возможность вывести их в новый класс, который инкапсулирует подмножество шагов семантически значимым образом.
Когда
MyClass
появляется больше зависимостей, потому что нам нужно вести логи, а также нужно уведомить веб-службу (пожалуйста, извините за примеры клише), тогда очень полезно легко увидеть, какие методы имеют какие зависимости.Такие инструменты, как R #, позволяют вам извлечь класс из набора частных статических методов несколькими нажатиями клавиш. Попробуйте сделать это, когда все частные вспомогательные методы тесно связаны с полем экземпляра, и вы увидите, что это может быть довольно головной болью.
источник
Как уже говорилось, у статических методов есть много преимуществ. Тем не мение; имейте в виду, что они будут жить в куче на протяжении всей жизни приложения. Недавно я провел день, отслеживая утечку памяти в службе Windows ... утечка была вызвана частными статическими методами внутри класса, который реализовал IDisposable и был последовательно вызван из оператора using. Каждый раз, когда этот класс создавался, в куче зарезервировалась память для статических методов внутри класса, к сожалению, когда класс был удален, память для статических методов не освобождалась. Это привело к тому, что занимаемая памятью служба потребляет доступную память сервера в течение нескольких дней с предсказуемыми результатами.
источник