usar - ¿Hay alguna manera de forzar una clase C#para implementar ciertas funciones estáticas?
qué son los atributos de clase estáticos (9)
El enfoque que lo acerca más a lo que necesita es un singleton, como sugirió Marc Gravell.
Las interfaces, entre otras cosas, le permiten proporcionar un cierto nivel de abstracción a sus clases para que pueda usar una API dada, independientemente del tipo que la implemente. Sin embargo, dado que SI necesita saber el tipo de una clase estática para usarla, ¿por qué querría aplicar esa clase para implementar un conjunto de funciones?
¿Tal vez podría usar un atributo personalizado como [ImplementsXXXInterface] y proporcionar alguna comprobación de tiempo de ejecución para asegurarse de que las clases con este atributo realmente implementen la interfaz que necesita?
Estoy desarrollando un conjunto de clases que implementan una interfaz común . Un consumidor de mi biblioteca debe esperar que cada una de estas clases implemente un cierto conjunto de funciones estáticas. ¿Hay alguna forma de que pueda decorar estas clases para que el compilador capte el caso donde una de las funciones no se implementa?
Sé que finalmente se detectará cuando se construya el código de consumo. Y también sé cómo evitar este problema usando una clase de fábrica.
Solo curiosidad por saber si hay alguna sintaxis / atributos para requerir funciones estáticas en una clase.
Ed Eliminó la palabra ''interfaz'' para evitar confusiones.
Lamentablemente, no, no hay nada como esto integrado en el lenguaje.
No, no hay soporte de idiomas para esto en C #. Hay dos soluciones que puedo pensar de inmediato:
- usar la reflexión en tiempo de ejecución; dedos cruzados y esperanza ...
- use un singleton / default-instance / similar para implementar una interfaz que declare los métodos
( actualización )
En realidad, siempre y cuando tengas pruebas unitarias, la primera opción no es tan mala como podrías pensar si (como yo) vienes de un estricto historial de "escritura estática". El hecho es; funciona bien en lenguajes dinámicos. Y, de hecho, así es exactamente como funciona mi código de operadores genéricos : espera tener los operadores estáticos. En tiempo de ejecución, si no lo hace, se reirá de ti con un tono de burla adecuado ... pero no se puede controlar en tiempo de compilación.
No, no tendría sentido esta característica. Las interfaces son básicamente una forma reducida de herencia múltiple. Le dicen al compilador cómo configurar la tabla de funciones virtuales para que los métodos virtuales no estáticos se puedan llamar correctamente en las clases descendientes. Los métodos estáticos no pueden ser virtuales, por lo tanto, no tiene sentido usar interfaces para ellos.
Si bien no hay soporte de idiomas para esto, puede usar una herramienta de análisis estático para aplicarlo. Por ejemplo, podría escribir una regla personalizada para FxCop que detecte la implementación de un atributo o interfaz en una clase y luego verifique la existencia de ciertos métodos estáticos.
El patrón singleton no ayuda en todos los casos. Mi ejemplo es de un proyecto real mío. No es artificial.
Tengo una clase (llamémosla "Widget") que hereda de una clase en un ORM de un tercero. Si instancia un objeto Widget (por lo tanto, creo una fila en el db) solo para asegurarme de que mis métodos estáticos están declarados, estoy haciendo un desastre mayor que el que estoy tratando de limpiar.
Si creo este objeto adicional en el almacén de datos, tengo que esconderlo de los usuarios, cálculos, etc.
Utilizo interfaces en C # para asegurarme de que implemento funciones comunes en un conjunto de clases.
Algunos de los métodos que implementan estas características requieren datos de instancia para ejecutarse. Codigo estos métodos como métodos de instancia y uso una interfaz C # para asegurarme de que existan en la clase.
Algunos de estos métodos no requieren datos de instancia, por lo que son métodos estáticos. Si pudiera declarar interfaces con métodos estáticos, el compilador podría verificar si estos métodos existen o no en la clase que dice que implementa la interfaz.
Esta es una gran pregunta y una que he encontrado en mis proyectos.
Algunas personas sostienen que las interfaces y clases abstractas existen solo para el polimorfismo, no para obligar a los tipos a implementar ciertos métodos. Personalmente, considero el polimorfismo como un caso de uso primario, y la implementación forzada es secundaria. Utilizo la técnica de implementación forzada con bastante frecuencia. Por lo general, aparece en el código de marco que implementa un patrón de plantilla. La clase base / template encapsula algunas ideas complejas, y las subclases proporcionan numerosas variaciones al implementar los métodos abstractos. Un beneficio pragmático es que los métodos abstractos proporcionan orientación a otros desarrolladores que implementan las subclases. Visual Studio incluso tiene la capacidad de stub los métodos para usted. Esto es especialmente útil cuando un desarrollador de mantenimiento necesita agregar una nueva subclase meses o años después.
La desventaja es que no hay soporte específico para algunos de estos escenarios de plantilla en C #. Los métodos estáticos son uno. Otro es constructores; idealmente, ISerializable debería obligar al desarrollador a implementar el constructor de serialización protegido.
El enfoque más fácil probablemente sea (como se sugirió anteriormente) utilizar una prueba automatizada para verificar que el método estático se implemente en los tipos deseados. Otra idea viable ya mencionada es implementar una regla de análisis estático.
Una tercera opción es usar un marco de Programación Orientada a Aspectos como PostSharp . PostSharp admite la validación de aspectos en tiempo de compilación. Puede escribir código .NET que refleje sobre el conjunto en tiempo de compilación, generando advertencias y errores arbitrarios. Por lo general, haces esto para validar que el uso de un aspecto es apropiado, pero no veo por qué no podrías usarlo también para validar reglas de plantilla.
Si está justo después de obtener esos errores del compilador, considere esta configuración:
- Defina los métodos en una interfaz.
- Declara los métodos con abstract.
- Implemente los métodos públicos estáticos, y haga que el método abstracto anule simplemente llame a los métodos estáticos.
Es un poco de código adicional, pero sabrá cuando alguien no está implementando un método requerido.
No. Básicamente parece que buscas una especie de "polimorfismo estático". Eso no existe en C #, aunque he sugerido una especie de noción de "interfaz estática" que podría ser útil en términos de genéricos .
Una cosa que podría hacer es escribir una prueba de unidad simple para verificar que todos los tipos en un conjunto particular obedezcan sus reglas. Si otros desarrolladores también implementarán la interfaz, puede poner ese código de prueba en un lugar común para que todos los que implementen la interfaz puedan probar fácilmente sus propios ensamblajes.