Ao criar uma classe que possui métodos privados internos, geralmente para reduzir a duplicação de código, que não exige o uso de nenhum campo de instância, existem vantagens de desempenho ou memória em declarar o método como estático?
Exemplo:
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;
}
Existe alguma vantagem em declarar os métodos GetInnerXml () como estáticos? Nenhuma resposta de opinião, por favor, tenho uma opinião.
c#
performance
NerdFury
fonte
fonte
Respostas:
Na página de regras do FxCop, consulte :
fonte
Quando estou escrevendo uma classe, a maioria dos métodos se enquadra em duas categorias:
Os métodos estáticos são úteis, porque, ao olhar para sua assinatura, você sabe que a chamada não usa nem modifica o estado da instância atual.
Veja este exemplo:
Se uma instância do estado da biblioteca for estragada, e eu estou tentando descobrir o porquê, posso excluir o findBook como o culpado, apenas a partir de sua assinatura.
Tento me comunicar o máximo possível com a assinatura de um método ou função, e essa é uma excelente maneira de fazer isso.
fonte
Library
possua um campo de instânciaList<Book> _books
para armazenar seus livros (não como vocêLibrary
provavelmente projetaria uma classe, mas w / e), e ela passa essa lista parafindBook
, e esse método estático chamabooks.Clear()
oubooks.Reverse()
assim por diante. Se você conceder a um método estático acesso a uma referência a algum estado mutável, esse método estático pode muito bem atrapalhar seu estado.Uma chamada para um método estático gera uma instrução de chamada na linguagem intermediária da Microsoft (MSIL), enquanto uma chamada para um método de instância gera uma instrução callvirt, que também verifica referências a objetos nulos. No entanto, na maioria das vezes a diferença de desempenho entre os dois não é significativa.
src: MSDN - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.110).aspx
fonte
Sim, o compilador não precisa passar o
this
ponteiro implícito para osstatic
métodos. Mesmo que você não o use no método da instância, ele ainda está sendo passado.fonte
Será um pouco mais rápido, pois esse parâmetro não foi passado (embora o custo de desempenho da chamada do método seja provavelmente consideravelmente maior do que essa economia).
Eu diria que a melhor razão pela qual posso pensar em métodos estáticos privados é que isso significa que você não pode alterar acidentalmente o objeto (pois não há esse ponteiro).
fonte
Isso obriga a lembrar também de declarar quaisquer membros com escopo de classe que a função use como estática também, o que deve economizar a memória de criar esses itens para cada instância.
fonte
Eu prefiro que todos os métodos privados sejam estáticos, a menos que realmente não possam ser. Eu preferiria muito o seguinte:
sobre todos os métodos que acessam o campo da instância. Por que é isso? Como esse processo de cálculo se torna mais complexo e a classe termina com 15 métodos auxiliares particulares, eu REALMENTE quero poder puxá-los para uma nova classe que encapsule um subconjunto de etapas de uma maneira semanticamente significativa.
Quando
MyClass
obtém mais dependências porque precisamos de log e também notificamos um serviço da web (desculpe os exemplos de clichê), é realmente útil ver facilmente quais métodos têm quais dependências.Ferramentas como o R # permitem extrair uma classe de um conjunto de métodos estáticos privados com apenas algumas teclas. Tente fazer isso quando todos os métodos auxiliares privados estiverem fortemente acoplados ao campo da instância e você verá que pode ser uma dor de cabeça.
fonte
Como já foi afirmado, existem muitas vantagens nos métodos estáticos. Contudo; lembre-se de que eles permanecerão na pilha pela vida útil do aplicativo. Recentemente, passei um dia rastreando um vazamento de memória em um serviço do Windows ... o vazamento foi causado por métodos estáticos privados dentro de uma classe que implementou IDisposable e foi consistentemente chamado a partir de uma instrução using. Cada vez que essa classe foi criada, a memória era reservada no heap para os métodos estáticos da classe; infelizmente, quando a classe foi descartada, a memória dos métodos estáticos não foi liberada. Isso fez com que a pegada de memória desse serviço consumisse a memória disponível do servidor dentro de alguns dias, com resultados previsíveis.
fonte