jueves, 17 de octubre de 2013

Limitar el tamaño de una propiedad del tipo string

La verdad que tengo mucha suerte de tener tanta gente realmente buena en el TimeLine de mi Twiter.

Así cuando lance la pregunta que es el título de este artículo, recibí ayuda e ideas de todo tipo que me han ayudado a llegar a alguna conclusión.

Y esa es que, no se puede de forma sencilla.

Los test que debían pasar eran dos y muy sencillos:

       [TestMethod]
      
public void Introducir_en_NIF_mas_de_9_caracteres()
        {
          
var empleado =newEmpleado();
          
var nif ="123456789012";

            empleado.NIF = nif;

          
Assert.AreEqual(empleado.NIF,"123456789");
           
        }
        [
TestMethod]
      
public void Introducir_en_NIF_5_caracteres()
        {
          
var empleado =newEmpleado();
           
var nif = "12345";

            empleado.NIF = nif;

           
Assert.AreEqual(empleado.NIF, "12345");

        }

Eduard Tomás ha realizado un precioso ejercicio en donde, por medio de conversiones explícitas y genéricos, consigue el objetivo. Eso sí, al coste de jartarte de escribir código. Mira el impresionante artículo que ha publicado en su blog.

También Javier Torrecilla y Juan José Luis Garcí me recomendaron utilizar descriptores/decoradores de la propiedad que están en el namespace de System.Component.ModelDataAnnotations. el problema es que el objetivo es una clase de una entidad que no tiene fachada de interface de usuario, para lo que es estas anotaciones.

[StringLength(9)]
public string NIF { get; set; }

Esto no pasó los test.

Por otro lado Nicolás Herrera me indicó que podría utilizar StringBuilder para la variable privada que utilice la propiedad, y que me permite limitar el tamaño.

private StringBuilder _int = new StringBuilder(9,9);
public string NIF { get { return _int.ToString(); } set { _int.Append(value.ToString()); } }

Lo cual consigue que pase perfectamente el segundo test, pero en el primero me rompe porque StringBuilder me lanza una excepción al intentar meter un valor mayor de lo permitido.

Como soy un agonías y no me gusta la programación basada en excepciones, pues también lo he desechado.

Y así volví a mi implementación original, que también me ha recomendado Marcos Rodríguez, Pedro Herrarte y Juan María Hernández, y que se trata de introducir la lógica para realizar el truncado en el set de la propiedad.

Así lo primero que hago es hacer un método dentro de la clase de la entidad que se va a ocupar de truncar la cadena. Y no cambiar nada, si tiene la longitud máxima o menos.

        private string CutTo(string cadena, int tamañoMaximo)
        {
           
if (cadena.Length > tamañoMaximo)
            { cadena = cadena.Substring(0, tamañoMaximo); }
           
           
return cadena;
        }

Y ahora sí, mi propiedad queda así:

        private string _int;
       
public string NIF { get { return _int; } set { _int = CutTo(value, 9); } }

Y esto si que me pasa los dos test con un hermoso verde.

Muchas gracias a todos los que me habéis aconsejado, este post va por vosotros CRACKS!!

No hay comentarios: