El método se puede hacer estático, pero ¿debería?

Resharper le gusta señalar múltiples funciones por página de asp.net que podrían estar estáticas. ¿Me ayuda si los hago estáticos? ¿Debo hacerlos estáticos y moverlos a una clase de utilidad?

Métodos estáticos versus métodos de instancia
10.2.5 Los miembros estáticos y de instancia de la Especificación del lenguaje C # explican la diferencia. En general, los métodos estáticos pueden proporcionar una mejora de rendimiento muy pequeña sobre los métodos de instancia, pero solo en situaciones algo extremas (consulte esta respuesta para obtener más información al respecto).

La regla CA1822 en FxCop o Code Analysis establece:

“Después de [marcar a los miembros como estáticos], el comstackdor emitirá sitios de llamadas no virtuales para estos miembros, lo que evitará una comprobación en tiempo de ejecución para cada llamada que asegure que el puntero del objeto actual no sea nulo. Esto puede generar una ganancia de rendimiento mensurable para el código sensible al rendimiento. En algunos casos, la falla al acceder a la instancia del objeto actual representa un problema de corrección “.

Clase de utilidad
No debe moverlos a una clase de utilidad a menos que tenga sentido en su diseño. Si el método estático se relaciona con un tipo particular, como el ToRadians(double degrees) se relaciona con una clase que representa angularjs, tiene sentido que ese método exista como un miembro estático de ese tipo (nota, este es un ejemplo enrevesado para el propósitos de la demostración).

Rendimiento, contaminación del espacio de nombres, etc. son todos secundarios en mi opinión. Pregúntate qué es lógico. ¿El método funciona lógicamente en una instancia del tipo o está relacionado con el tipo en sí? Si es el último, conviértalo en un método estático. Solo muévala a una clase de utilidad si está relacionada con un tipo que no está bajo su control.

A veces hay métodos que lógicamente actúan en una instancia pero que aún no utilizan el estado de la instancia. Por ejemplo, si estuviese construyendo un sistema de archivos y tuviera el concepto de un directorio, pero aún no lo hubiera implementado, podría escribir una propiedad que devuelva el tipo de objeto del sistema de archivos, y siempre sería solo “archivo” – pero está lógicamente relacionado con la instancia, por lo que debe ser un método de instancia. Esto también es importante si desea que el método sea virtual: su implementación particular puede no necesitar estado, pero las clases derivadas sí pueden. (Por ejemplo, preguntarle a una colección si es o no de solo lectura; es posible que aún no haya implementado una forma de solo lectura de esa colección, pero es claramente una propiedad de la colección en sí, no del tipo).

Marcar un método como static dentro de una clase hace que sea obvio que no usa ningún miembro de instancia que pueda ser útil saber al pasar por el código. No necesariamente tiene que moverlo a otra clase a menos que esté destinado a ser compartido por otra clase que esté tan estrechamente asociada, conceptualmente.

Estoy seguro de que esto no está sucediendo en su caso, sino de un “mal olor” que he visto en algún código que he tenido que sufrir manteniendo el uso de una gran cantidad de métodos estáticos.

Desafortunadamente, eran métodos estáticos que asumían un estado de aplicación particular. (¿Por qué no, solo tendremos un usuario por aplicación! ¿Por qué no hacer que la clase de Usuario haga un seguimiento de eso en variables estáticas?) Eran formas glorificadas de acceder a las variables globales. También tenían constructores estáticos (!), Que casi siempre son una mala idea. (Sé que hay un par de excepciones razonables).

Sin embargo, los métodos estáticos son bastante útiles cuando tienen en cuenta la lógica de dominio que en realidad no depende del estado de una instancia del objeto. Pueden hacer que tu código sea mucho más legible.

Solo asegúrate de ponerlos en el lugar correcto. ¿Los métodos estáticos manipulan intrusivamente el estado interno de otros objetos? ¿Se puede argumentar que su comportamiento pertenece a una de esas clases? Si no está separando las preocupaciones adecuadamente, es posible que tenga dolores de cabeza más adelante.

Esta es una lectura interesante:

http://thecuttingledge.com/?p=57

ReSharper en realidad no sugiere que hagas que tu método sea estático. Debería preguntarse por qué ese método está en esa clase en lugar de, por ejemplo, una de las clases que aparece en su firma …

pero aquí está lo que dice la documentación de resharper: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static

Solo para agregar a la respuesta de @Jason True, es importante darse cuenta de que simplemente poner ‘estático’ en un método no garantiza que el método sea ‘puro’. Será sin estado con respecto a la clase en la que se declara, pero puede acceder a otros objetos “estáticos” que tienen estado (configuración de la aplicación, etc.), esto no siempre es malo, pero una de las razones por las cuales Personalmente, prefiero los métodos estáticos cuando puedo, si son puros, puedes probarlos y razonar sobre ellos de forma aislada, sin tener que preocuparte por el estado circundante.

Debe hacer lo que es más legible e intuitivo en un escenario dado.

El argumento de rendimiento no es bueno, excepto en las situaciones más extremas, ya que lo único que realmente está sucediendo es que un parámetro adicional ( this ) se está introduciendo en la stack, por ejemplo, en los métodos.

Para la lógica compleja dentro de una clase, he encontrado que los métodos estáticos privados son útiles para crear una lógica aislada, en la cual las entradas de la instancia están claramente definidas en la firma del método y no pueden ocurrir efectos secundarios de la instancia. Todas las salidas deben ser a través del valor de retorno o los parámetros de salida / ref. Descomponer la lógica compleja en bloques de código sin efectos secundarios puede mejorar la legibilidad del código y la confianza del equipo de desarrollo en él.

Por otro lado, puede llevar a una clase contaminada por una proliferación de métodos de utilidad. Como es habitual, la nomenclatura lógica, la documentación y la aplicación coherente de las convenciones de encoding de equipo pueden aliviar esto.

ReSharper no verifica la lógica. Solo verifica si el método usa miembros de la instancia. Si el método es privado y solo lo llaman (tal vez solo uno) de los métodos de instancia, este es un signo para permitir que sea un método de instancia.

Si las funciones se comparten en muchas páginas, también podría ponerlas en una clase de página base, y luego tener todas las páginas asp.net que usen esa funcionalidad heredada (y las funciones también podrían ser estáticas).

Hacer que un método sea estático significa que puede llamar al método desde fuera de la clase sin crear primero una instancia de esa clase. Esto es útil cuando se trabaja con objetos de terceros o complementos. Imagine si primero tenía que crear un objeto de consola “con” antes de llamar a con.Writeline ();

Ayuda a controlar la contaminación del espacio de nombres.

Solo mi tuppencia: Agregar todos los métodos estáticos compartidos a una clase de utilidad le permite agregar

 using static className; 

a sus instrucciones de uso, lo que hace que el código sea más rápido de escribir y más fácil de leer. Por ejemplo, tengo un gran número de lo que se llamaría “variables globales” en algún código que heredé. En lugar de hacer variables globales en una clase que era una clase de instancia, las configuré todas como propiedades estáticas de una clase global. Hace el trabajo, si es desordenado, y puedo simplemente hacer referencia a las propiedades por su nombre porque ya tengo el espacio de nombres estático al que se hace referencia.

No tengo idea si esto es una buena práctica o no. Tengo tanto para aprender sobre C # 4/5 y tanto código heredado para refactorizar que solo estoy tratando de dejar que los consejos de Roselyn me guíen.

Joey