Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

283
Vistas
Validar argumentos List<string> dinámicamente en C#

Dado:

  • Número de argumentos
  • Tipo de cada argumento
  • List<string> args

Digamos que tengo un List<string> args de la siguiente manera:

 List<string> args = new List<string> { "1", "helloworld", "3" }

Quiero validar args de la siguiente manera, puedo llamar a cualquiera de estos métodos según lo requiera mi código.

Métodos de validación:

 public bool isValidOneString(List<string> args) { return args.Count() == 1; } public bool isValidTwoStrings(List<string> args) { return args.Count() == 2; } public bool isValidThreeStrings(List<string> args) { return args.Count() == 3; } public bool isValidOneStringTwoFloat(List<string> args) { bool isValid = args.Count() == 2; if(!isValid) return false; float valueAfterParse; isValid = float.TryParse(args[1], out valueAfterParse); return isValid; } public bool isValidOneFloatTwoDoubleThreeInt32(List<string> args) { bool isValid = args.Count() == 3; if(!isValid) return false; float valueAfterParse; isValid = float.TryParse(args[0], out valueAfterParse); if(!isValid) return false; Double valueAfterParse; isValid = Double.TryParse(args[0], out valueAfterParse); if(!isValid) return false; Int32 valueAfterParse; isValid = Int32.TryParse(args[0], out valueAfterParse); if(!isValid) return false; return isValid; }

Problema: como puede ver, eventualmente terminaré teniendo una cantidad infinita de métodos de validación. ¿Hay alguna manera de que pueda tener solo 1 método de validación como por ejemplo a continuación? (que puede hacerse cargo de todos los casos posibles)

 public bool isValid(List<string> args, int totalExpectedCountOfArgs, List<string> typesOfEachArg) { bool isValid = args.Count() == totalExpectedCountOfArgs; if(!isValid) return false; int i = 0; foreach(string dataType : typesOfEachArg) { isValid = typeOf(dataType).TryParse(args[i], out typeOf(dataType)); //I AM GETTING ERROR HERE BECAUSE I DONT KNOW HOW TO GENERIFY THIS if(!isValid) return false; i++; } return true; }

Y luego puedo simplemente llamar al método anterior isValid(args, 3, List<string>{"float", "Int32", "Double"}) ? Pero recibo un error en mi método genérico, ¿alguien sabe cómo validar los tipos de datos de forma genérica y dinámica?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Qué tal si:

 public bool IsValid<TArg0>(List<string> args) => args.Length == 1 && IsValidCore<TArg0>(args[0]); public bool IsValid<TArg0, TArg1>(List<string> args); => args.Length == 2 && IsValidCore<TArg0>(args[0]) && IsValidCore<TArg1>(args[1]); public bool IsValid<TArg0, TArg1, TArg2>(List<string> args) => args.Length == 3 && IsValidCore<TArg0>(args[0]) && IsValidCore<TArg1>(args[1]) && IsValidCore<TArg2>(args[2]);

Entonces, en lugar de isValidOneFloatTwoDoubleThreeInt32(args) , usaría IsValid<float, double, int>(args);

etc, para un pequeño límite superior N de TArgN . El problema es que necesita un analizador basado en genéricos, pero eso no es necesariamente tan malo si solo necesita poder manejar tipos específicos, al marcar la T :

 private static bool IsValidCore<T>(string value) { if (typeof(T) == typeof(string)) return true; if (typeof(T) == typeof(int)) return int.TryParse(...); if (typeof(T) == typeof(float)) return float.TryParse(...); if (typeof(T) == typeof(double)) return double.TryParse(...); // etc for some finite number of types throw new NotSupportedException("Not considered: " + typeof(T).Name); }
over 4 years ago · Santiago Trujillo Denunciar

0

Tal vez ayudaría si tuviera un método de este tipo para validadores arbitrarios:

 public static bool IsValid<T>(List<T> args, params Func<List<T>, bool>[] validators) => validators.All(validate => validate(args));

Ahora podría, por ejemplo, validarlo de esta manera:

 bool isValid = IsValid(args, list => list.Count == 3);

o con un método existente:

 bool isValid = IsValid(args, isValidThreeStrings);

o con ambos:

 bool isValid = IsValid(args, list => list.Count == 3, isValidThreeStrings);

o con múltiples:

 Func<List<string>, bool>[] allValidators = new Func<List<string>, bool>[] { list => list.Count == 2, list => float.TryParse(list[1], out float val), isValidOneFloatTwoDoubleThreeInt32 }; bool isValid = IsValid(args, allValidators);

Si te gusta y quieres reutilizarlo para todo tipo de listas/matrices/lo que sea, puedes crear un método de extensión como este. Tenga en cuenta que se necesita IEnumerable<T> :

 public static class EnumerableExtensions { public static bool AreAllValid<T>(this IEnumerable<T> items, params Func<IEnumerable<T>, bool>[] validators) => validators?.All(validate => validate(items)) ?? throw new ArgumentNullException(nameof(validators)); }
over 4 years ago · Santiago Trujillo Denunciar

0

Sugiero extraer model , que sea un diccionario con Type como clave y validator Func como valor:

 private static Dictionary<Type, Func<string, bool>> s_Validators = new Dictionary<Type, Func<string, bool>>() { {typeof(string), (x) => true }, {typeof(int), (x) => int.TryParse(x, out var _) }, {typeof(float), (x) => float.TryParse(x, out var _) }, {typeof(double), (x) => double.TryParse(x, out var _) }, //TODO: add more type validators here };

Entonces el validador puede ser:

 private static bool IsValid(IEnumerable<string> arguments, params Type[] signature) { if (null == arguments) return false; // or throw ArgumentNullException if (null == signature) return false; int index = 0; foreach (string arg in arguments) { // Too many arguments if (index >= signature.Length) return false; // For argument to be valid we should know type and pass validation if (!s_Validators.TryGetValue(signature[index++], out var validator) || !validator(arg)) return false; } // if index < signature.Length we have too few arguments return index == signature.Length; }

Uso:

 List<string> args = new List<string> { "1", "helloworld", "3" }; bool isValid = IsValid(args, typeof(int), typeof(string), typeof(int));

Si desea tener string s en lugar de Type s, cambie s_Validators e IsValid un poco:

 private static Dictionary<string, Func<string, bool>> s_Validators = new Dictionary<string, Func<string, bool>>() { {"string", (x) => true }, {"int", (x) => int.TryParse(x, out var _) }, ... }; private static bool IsValid(IEnumerable<string> arguments, params string[] signature) { ... }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda