tipos see remarks metodos generate funciones example cref consola c# .net refactoring resharper static-methods

remarks - see cref c#



El método puede hacerse estático, pero ¿debería serlo? (13)

A Resharper le gusta señalar múltiples funciones por página de 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?


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


Debe hacer lo que sea más legible e intuitivo en un escenario determinado.

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á insertando en la pila para los métodos de ejemplo.


El rendimiento, la contaminación del espacio de nombres, etc. son secundarios en mi opinión. Pregúntate a ti mismo qué es lógico. ¿Está el método operando lógicamente en una instancia del tipo, o está relacionado con el tipo en sí? Si es lo último, conviértelo 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 que no utilizan ningún estado de la instancia todavía . Por ejemplo, si estuviera creando un sistema de archivos y obtuviera el concepto de un directorio, pero todavía no lo hubiera implementado, podría escribir una propiedad que devuelva el tipo de objeto del sistema de archivos, y siempre sería justo "archivo" - pero está relacionado lógicamente con la instancia, y por lo tanto 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 en particular puede no necesitar estado, pero las clases derivadas pueden hacerlo. (Por ejemplo, preguntar a una colección si es de solo lectura o no, es posible que aún no haya implementado una forma de solo lectura de esa colección, pero claramente es una propiedad de la colección en sí, no del tipo).



Estoy seguro de que esto no está sucediendo en su caso, pero un "mal olor" que he visto en algunos códigos que he tenido que sufrir a través del mantenimiento ha utilizado 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é seguro, solo tendremos un usuario por aplicación? ¿Por qué no hacer que la clase Usuario realice un seguimiento de eso en las 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 eliminan la lógica de dominio que no depende realmente del estado de una instancia del objeto. Pueden hacer que su código sea mucho más legible.

Solo asegúrate de ponerlos 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 se está separando las preocupaciones de manera adecuada, es posible que tenga dolores de cabeza más adelante.


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 de terceros. Imagínese si primero tuviera que crear un objeto de consola "con" antes de llamar a con.Writeline ();


Marcar un método como static dentro de una clase hace que sea obvio que no utiliza ningún miembro de instancia, lo que puede ser útil saber cuando se hojea el código. No necesariamente tiene que pasarlo a otra clase a menos que esté destinado a ser compartido por otra clase que esté tan estrechamente asociada, en cuanto a conceptos.


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 que las entradas de 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 de valores de retorno o parámetros de salida / referencia. Romper 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 de costumbre, la nomenclatura lógica, la documentación y la aplicación coherente de las convenciones de codificación en equipo pueden aliviar esto.


ReSharper no comprueba la lógica. Solo verifica si el método usa miembros de instancia. Si el método es privado y solo se invoca mediante (quizás solo uno) los métodos de instancia, esto es un signo para dejar que sea un método de instancia.


Si las funciones se comparten en muchas páginas, también puede colocarlas en una clase de página base y, a continuación, hacer que todas las páginas asp.net que utilizan esa funcionalidad se hereden de ella (y las funciones también podrían ser estáticas).


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 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 establezco todas como propiedades estáticas de una clase global. Hace el trabajo, si es confuso, y solo puedo hacer referencia a las propiedades por 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 mucho que aprender sobre C # 4/5 y tanto código heredado para refactorizar que solo trato de dejar que los consejos de Roselyn me guíen.

Joey


Solo para agregar a la answer @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 bien puede acceder a otros objetos ''estáticos'' que tienen estado (configuración de la aplicación, etc.), esto puede no ser siempre algo malo, pero una de las razones por las que Personalmente tiendo a preferir los métodos estáticos cuando puedo, es que si son puros, puedes probarlos y razonar de forma aislada, sin tener que preocuparte por el estado circundante.


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

La regla CA1822 en FxCop o Code Analysis declara:

"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. para código sensible al rendimiento. En algunos casos, el hecho de no tener acceso a la instancia de 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) 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 complicado para el fines de demostración).