Al crear una clase que tiene métodos privados internos, generalmente para reducir la duplicación de código, que no requieren el uso de ningún campo de instancia, ¿existen ventajas de rendimiento o memoria para declarar el método como estático?
Ejemplo:
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;
}
¿Hay alguna ventaja en declarar los métodos GetInnerXml () como estáticos? No hay respuestas de opinión por favor, tengo una opinión.
c#
performance
NerdFury
fuente
fuente
Respuestas:
Desde la página de reglas de FxCop sobre esto:
fuente
Cuando escribo una clase, la mayoría de los métodos se dividen en dos categorías:
Los métodos estáticos son útiles, porque con solo mirar su firma, sabes que la llamada no usa ni modifica el estado de la instancia actual.
Toma este ejemplo:
Si alguna vez se estropea una instancia del estado de la biblioteca, y estoy tratando de averiguar por qué, puedo descartar que FindBook sea el culpable, solo por su firma.
Intento comunicarme todo lo que puedo con la firma de un método o función, y esta es una excelente manera de hacerlo.
fuente
Library
tiene un campo de instanciaList<Book> _books
para almacenarlo de libros (no cómo le gustaría diseñar unaLibrary
clase, probablemente, pero w / e), y pasa a esta listafindBook
, y que las llamadas a métodos estáticosbooks.Clear()
obooks.Reverse()
y así sucesivamente. Si le da acceso a un método estático a una referencia a algún estado mutable, entonces ese método estático puede arruinar su estado.Una llamada a un método estático genera una instrucción de llamada en el lenguaje intermedio de Microsoft (MSIL), mientras que una llamada a un método de instancia genera una instrucción callvirt, que también busca referencias de objetos nulos. Sin embargo, la mayoría de las veces la diferencia de rendimiento entre los dos no es significativa.
src: MSDN - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.110).aspx
fuente
Sí, el compilador no necesita pasar el
this
puntero implícito a losstatic
métodos. Incluso si no lo usa en su método de instancia, todavía se está pasando.fuente
Será un poco más rápido ya que no se pasa este parámetro (aunque el costo de rendimiento de llamar al método es probablemente mucho más que este ahorro).
Diría que la mejor razón por la que puedo pensar en métodos estáticos privados es que significa que no puede cambiar accidentalmente el objeto (ya que no hay este puntero).
fuente
Esto le obliga a recordar que también debe declarar cualquier miembro con ámbito de clase que la función utilice también como estático, lo que debería ahorrar la memoria de crear esos elementos para cada instancia.
fuente
Prefiero que todos los métodos privados sean estáticos a menos que realmente no puedan serlo. Preferiría mucho lo siguiente:
sobre cada método que accede al campo de instancia. ¿Por qué es esto? Debido a que este proceso de cálculo se vuelve más complejo y la clase termina con 15 métodos de ayuda privados, REALMENTE quiero poder llevarlos a una nueva clase que encapsule un subconjunto de los pasos de una manera semánticamente significativa.
Cuando
MyClass
tenemos más dependencias porque necesitamos iniciar sesión y también tenemos que notificar a un servicio web (disculpe los ejemplos cliché), entonces es realmente útil ver fácilmente qué métodos tienen qué dependencias.Herramientas como R # le permite extraer una clase de un conjunto de métodos estáticos privados en unas pocas pulsaciones de teclas. Intente hacerlo cuando todos los métodos de ayuda privada estén estrechamente vinculados al campo de instancia y verá que puede ser un gran dolor de cabeza.
fuente
Como ya se ha dicho, los métodos estáticos tienen muchas ventajas. Sin embargo; tenga en cuenta que vivirán en el montón durante la vida de la aplicación. Recientemente, pasé un día rastreando una pérdida de memoria en un Servicio de Windows ... la pérdida fue causada por métodos estáticos privados dentro de una clase que implementó IDisposable y fue llamada constantemente desde una declaración de uso. Cada vez que se creaba esta clase, la memoria se reservaba en el montón para los métodos estáticos dentro de la clase, desafortunadamente, cuando se eliminaba la clase, no se liberaba la memoria para los métodos estáticos. Esto provocó que la huella de memoria de este servicio consumiera la memoria disponible del servidor en un par de días con resultados predecibles.
fuente