Pregunta

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?

¿Fue útil?

Solución

Métodos estáticos versus métodos de instancia
10.2.5 Miembros estáticos y de instancia de C # Especificación de lenguaje explica la diferencia. En general, los métodos estáticos pueden proporcionar una mejora de rendimiento muy pequeña con respecto a los métodos de instancia, pero solo en situaciones un tanto extremas (consulte esta respuesta para Algunos detalles más sobre eso).

La regla CA1822 en FxCop o los estados de análisis de código:

  

" 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   runtime para cada llamada que asegure que el puntero del objeto actual es   no nulo Esto puede resultar en una ganancia de rendimiento medible para   Código sensible al rendimiento. En algunos casos, la falta de acceso a la   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 método de 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 los propósitos de demostración).

Otros consejos

En mi opinión, el rendimiento, la contaminación del espacio de nombres, etc. son secundarios. 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 no lo hubiera implementado todavía, podría escribir una propiedad que devuelva el tipo de objeto del sistema de archivos, y siempre sería justo " 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 que el método sea virtual: su implementación en particular puede que no necesite un estado, pero las clases derivadas pueden. (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).

Marcar un método como static dentro de una clase hace 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 moverlo a otra clase a menos que esté destinado a ser compartido por otra clase que esté tan estrechamente asociada, en cuanto a conceptos.

Estoy seguro de que esto no está sucediendo en tu caso, pero un " mal olor " He visto en algunos códigos que he tenido que sufrir a través del mantenimiento de 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 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 tu código sea mucho más legible.

Solo asegúrate de colocarlos en el lugar correcto. ¿Los métodos estáticos están manipulando de forma intrusiva el estado interno de otros objetos? ¿Se puede demostrar que su comportamiento pertenece a una de esas clases? Si no se está separando las inquietudes de manera adecuada, es posible que luego tenga dolores de cabeza.

Esta es una lectura interesante:

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

ReSharper no está realmente sugiriendo que el método sea estático. Debería preguntarse por qué ese método está en esa clase en lugar de, digamos, 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 @Jason True's respuesta , es importante darse cuenta de que el solo hecho de 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.

Debes 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 está sucediendo realmente es que un parámetro adicional ( este ) se está insertando en la pila para los métodos de instancia.

Para la lógica compleja dentro de una clase, he encontrado métodos privados estáticos ú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. La división de 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) métodos de instancia, esto es una señal 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 pueden ser estáticas).

Hacer un método estático significa que puedes 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 ();

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

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 he heredado. 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top