A Resharper le gusta señalar múltiples funciones por página asp.net que podrían hacerse estáticas. ¿Me ayuda si los hago estáticos? ¿Debo hacerlos estáticos y moverlos a una clase de utilidad?
A Resharper le gusta señalar múltiples funciones por página asp.net que podrían hacerse estáticas. ¿Me ayuda si los hago estáticos? ¿Debo hacerlos estáticos y moverlos a una clase de utilidad?
Respuestas:
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 detalles al respecto).
La regla CA1822 en FxCop o Code Analysis establece:
"Después de [marcar miembros como estáticos], el compilador emitirá sitios de llamadas no virtuales a estos miembros, lo que evitará una verificación en tiempo de ejecución para cada llamada que garantice que el puntero del objeto actual no sea nulo. Esto puede resultar en una ganancia de rendimiento medible para código sensible al rendimiento. En algunos casos, el hecho de no 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 un ToRadians(double degrees)
método se relaciona con una clase que representa ángulos, tiene sentido que ese método exista como un miembro estático de ese tipo (nota, este es un ejemplo enrevesado para fines de demostración).
El rendimiento, la contaminación del espacio de nombres, etc. son todos secundarios en mi opinión. Pregúntate qué es lógico. ¿Funciona lógicamente el método en una instancia del tipo o está relacionado con el tipo en sí? Si es lo último, conviértalo en un método estático. Solo muévalo a una clase de utilidad si está relacionado con un tipo que no está bajo su control.
A veces hay métodos que actúan lógicamente en una instancia pero no pasan a utilizar cualquiera de estado de la instancia todavía . Por ejemplo, si estuviera creando 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 debería ser un método de instancia. Esto también es importante si desea hacer que el método sea virtual; su implementación particular puede no necesitar estado, pero las clases derivadas pueden. (Por ejemplo, preguntarle a una colección si es de solo lectura o no, es posible que todavía 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, lo que puede ser útil para saber al hojear 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, en cuanto al concepto.
Estoy seguro de que esto no está sucediendo en su caso, pero un "mal olor" que he visto en algún código que he tenido que sufrir al mantener usado muchos métodos estáticos.
Desafortunadamente, eran métodos estáticos que asumían un estado de aplicación particular. (¡por qué seguro, solo tendremos un usuario por aplicación! ¿Por qué no hacer que la clase Usuario haga un seguimiento de eso en las variables estáticas?) Fueron formas gloriosas 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 factorizan la lógica de dominio que en realidad no depende del estado de una instancia del objeto. Pueden hacer que su código sea mucho más legible.
Solo asegúrese de colocarlos en el lugar correcto. ¿Los métodos estáticos están manipulando 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 no está sugiriendo que haga que su 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 esto es lo que dice documentary 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 solo poner "estático" en un método no garantiza que el método sea "puro". No tendrá estado con respecto a la clase en la que se declara, pero bien puede acceder a otros objetos 'estáticos' que tienen estado (configuración de la aplicación, etc.), esto no siempre puede ser algo malo, pero una de las razones por las que Personalmente, prefiero los métodos estáticos cuando puedo, es que si son puros, puede probarlos y razonar sobre ellos de forma aislada, sin tener que preocuparse por el estado circundante.
Debe hacer lo que sea 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 pila por ejemplo.
Para la lógica compleja dentro de una clase, he encontrado que los métodos estáticos privados son útiles para crear lógica aislada, en la que las entradas de instancia están claramente definidas en la firma del método y no pueden producirse efectos secundarios de instancia. Todas las salidas deben ser a través del valor de retorno o los parámetros out / ref. Desglosar 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 conducir a una clase contaminada por la proliferación de métodos de utilidad. Como de costumbre, la denominación lógica, la documentación y la aplicación coherente de las convenciones de codificación del equipo pueden aliviar esto.
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 o complementos de proveedores externos. Imagine si primero tuviera que crear un objeto de consola "con" antes de llamar a con.Writeline ();
Ayuda a controlar la contaminación del espacio de nombres.
Class.a_core_function( .. )
vsa_core_function( .. )
Solo mi tuppence: agregar todos los métodos estáticos compartidos a una clase de utilidad le permite agregar
using static className;
a sus declaraciones 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 una gran cantidad de lo que se llamarían "variables globales" en algún código que heredé. En lugar de crear 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 solo puedo hacer referencia a las propiedades por nombre porque ya tengo referenciado el espacio de nombres estático.
No tengo idea si esta es una buena práctica o no. Tengo mucho que 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
Espero que ya haya entendido la diferencia entre los métodos estáticos y de instancia. Además, puede haber una respuesta larga y una respuesta corta. Las respuestas largas ya son proporcionadas por otros.
Mi respuesta corta: Sí, puedes convertirlos a métodos estáticos si Resharper sugiere. No hay daño al hacerlo. Más bien, al hacer que el método sea estático, en realidad lo está protegiendo para que, innecesariamente, no deslice a ningún miembro de la instancia a ese método. De esa manera, puede lograr un principio de OOP " Minimizar la accesibilidad de clases y miembros ".
Cuando ReSharper sugiere que un método de instancia se puede convertir en un método estático, en realidad le dice: "¿Por qué ... este método está en esta clase ya que no está utilizando ninguno de sus estados?" Entonces, te da que pensar. Entonces, es usted quien puede darse cuenta de la necesidad de mover ese método a una clase de utilidad estática o no. De acuerdo con los principios de SOLID, una clase debe tener solo una responsabilidad central. Entonces, puedes hacer una mejor limpieza de tus clases de esa manera. A veces, necesita algunos métodos auxiliares incluso en su clase de instancia. Si ese es el caso, puede mantenerlos dentro de un #region helper.