2009-02-03 7 views
6

En mi código hay varias cadenas que se utilizan como claves para acceder a los recursos. Estas claves tienen un formato específico, p.Comprobando el formato de cadena en tiempo de compilación en C#

string key = "ABC123"; 

En la actualidad, todas estas claves se almacenan como cadenas, pero me gustaría hacer las cosas más robusto y con seguridad de tipos. Idealmente, me gustaría comprobar que las cadenas estén en el formato correcto en el momento de la compilación.

La siguiente etapa es crear una clase ResourceKey que se inicializa a partir de una cadena. Luego puedo verificar el formato de la cadena en tiempo de ejecución, p.

ResourceKey key = "ABC123"; 

donde ResourceKey se define como:

using System.Diagnostics; 
using System.Text.RegularExpressions; 

class ResourceKey 
{ 
    public string Key { get; set; } 

    public static implicit operator ResourceKey (string s) 
    { 
     Debug.Assert(Regex.IsMatch(s, @"^[A-Z]{3}[0-9]{3}$")); 
     return new ResourceKey() { Key = s }; 
    } 
} 

Lo que realmente me gustaría hacer es tener una especie de aserción de tiempo de compilación para que el programa no puede construir si alguien trata de usar una clave inválida p.ej.

ResourceKey k1 = "ABC123"; // compiles 
ResourceKey k2 = "DEF456"; // compiles 
ResourceKey k3 = "hello world"; // error at compile time 

¿Hay alguna manera de lograr esto?

Gracias

Respuesta

8

Usted puede comprobar los valores con una unidad de prueba. Uno de mis compañeros de trabajo tuvo que hacer algo similar a esto en un proyecto en el que necesitábamos asegurar que todas las clases en un determinado espacio de nombres tenían ciertos atributos aplicados.

Ejecute las pruebas unitarias con su compilación (¿de todos modos lo hace bien? :) o como parte de una compilación de integración. Esto mantendrá su fuente más limpia y no tendrá que introducir código que haga afirmaciones.

+0

Estoy de acuerdo en esto, sugieren también compruebe http://www.postsharp.org/ para hacer asegurar/después de la lógica – kentaromiura

+0

Buena idea, pero desafortunadamente estas claves están distribuidas entre decenas de miles de líneas de código heredado, la gran mayoría no está cubierta por pruebas unitarias. ¡Aunque estamos llegando! – roomaroo

+0

¡Lamento escuchar eso! –

1

¿Realmente quiere estas claves codificadas en su aplicación? ¿No sería mejor tenerlos en un archivo de configuración? Entonces, si hay algún problema después de la compilación, es simplemente un problema de configuración de tiempo de ejecución.

+0

Otra ventaja de un almacén basado en XML para los nombres clave es que el archivo siempre se puede validar contra un Esquema. – Cerebrus

+0

Las claves son referencias a entradas en un archivo XML. Si todas sus configuraciones están en un archivo de configuración, aún necesita una forma de especificar qué configuración mirar. – roomaroo

+0

Dado que parece que estas son las claves de un archivo de recursos, ponerlas en una configuración significa que solo necesitará otro conjunto de cadenas codificadas para obtener esos valores. En algún momento, debe codificar una clave de cadena en el código o proporcionarla como entrada, lo que no sería práctico aquí. –

2

Creo que agregaría una clase de Configuraciones y las almacenaría allí en lugar de crear un tipo nuevo. La clase de configuración puede respaldarse con un archivo de configuración de la aplicación que los hará más fáciles de cambiar a través de cambios en el archivo de configuración si es necesario. Sin embargo, si no los especifica en el archivo de configuración, usará los valores que establezca como predeterminados.

También iría a la ruta de prueba de la unidad. Deberá usar el atributo InternalsVisibleTo en su archivo Assembly.cs ya que no creo que la Configuración se pueda usar fuera del proyecto si no lo hace.

+0

+1 para archivo de configuración e InternalsVisibleTo –

1

AdamRalph tiene un punto, pero el punto de venta libre también funciona, si se hace bien en tiempo de compilación, que nunca tendrá problemas de configuración en tiempo de ejecución (asumiendo los valores correctos no pueden cambiar)

Fuera de eso, Las habilidades de tiempo de compilación de C# son absolutas Junk. Su casi nada se puede hacer en tiempo de compilación. La mejor disponible que conozco es la plantilla where cláusula. Si tuviera que adivinar, diría que esta es una elección de diseño intencional de Anders Hejlsberg, ya que parece coincidir con el resto del lenguaje

El punto de Andrew Hare sobre unittest + la reflexión es tan buena como la que tenía esperar. Un compañero de trabajo mío lo usa para probar que cualquier clase que podría usarse en casos particulares implementó correctamente algún protocolo.

1

Si las teclas se denominan de acuerdo con las mismas reglas que los identificadores de C#, o tal vez incluso más limitante, y conocido y finito, se puede usar una enumeración:

public enum ResourceKeys 
{ 
    ABC123, 
    DEF456 
} 
Cuestiones relacionadas