tipos serial que identificarlos finalidad cual como argumentos argumento argumentar argumentacion argumenta c# .net argument-validation

c# - serial - tipos de argumentos



¿Cuál es la mejor práctica en caso de que un argumento sea nulo? (7)

Debe pensar en el método, lo que debe hacer y con qué datos. Si los valores nulos representan condiciones de falla reales, use excepciones. Si los valores nulos son aceptables, acéptelos.

Piense en los principios del diseño por contrato , específicamente cuáles son las condiciones previas a su función, y estandarice una forma de aplicarlos (lo que tanto Matt como Lou sugieren en sus respuestas, por lo que no necesito entrar en detalles).

Otra cosa importante a considerar es el tamaño de las firmas de su método. Si tiene muchos parámetros para sus métodos, esto probablemente significa que tiene malas abstracciones. Puede reducir el número de comprobaciones de parámetros que debe realizar si agrupa los parámetros en objetos de colección y utiliza esos objetos como parámetros. Puede mover la comprobación de parámetros a esos objetos en lugar de tener que verificarlos en cada función que los use.

Entonces, en lugar de pasar diez parámetros relacionados a cada función, descubra los pocos que se utilizan en cada función y los empaqueta en un objeto, e incluya en ese objeto los métodos para validar los parámetros. Esto tiene la ventaja adicional de ser fácil de cambiar si las reglas con respecto a un parámetro necesitan actualizarse.

Al validar la entrada de los métodos, solía verificar si el argumento es nulo y, si es así, lanzo una ArgumentNullException. Hago esto para todos y cada uno de los argumentos en la lista, así que termino con un código como este:

public User CreateUser(string userName, string password, string Email, string emailAlerts, string channelDescription) { if (string.IsNullOrEmpty(userName)) throw new ArgumentNullException("Username can''t be null"); if (string.IsNullOrEmpty(Email)) throw new ArgumentNullException("Email can''t be null"); //etc, etc, etc }

¿Esta bien? ¿Por qué debería hacer esto? ¿Estaría bien si simplemente agrupara todas las comprobaciones y devolviera un valor nulo en lugar de lanzar la excepción? ¿Cuál es la mejor práctica para abordar esta situación?

PD: Quiero cambiar esto, porque con métodos largos, se vuelve muy tedioso hacerlo.
Ideas?


Haz una clase ArgChecker con algo como esto

ArgChecker.ThrowOnStringNullOrEmpty(userName, "Username");

donde ThrowOnStringNullOrEmpty es

public static void ThrowOnStringNullOrEmpty(string arg, string name) { if (string.IsNullOrEmpty(arg)) throw new ArgumentNullException(name + " can''t be null"); }

También puedes intentar procesar una lista de argumentos utilizando un argumento params, como:

public static void ThrowOnAnyStringNullOrEmpty(params string[] argAndNames) { for (int i = 0; i < argAndName.Length; i+=2) { ThrowOnStringNullOrEmpty(argAndNames[i], argAndNames[i+1]); } }

y llamar así

ArgChecker.ThrowOnAnyStringNullOrEmpty(userName, "Username", Email, "email");


Me quedaría con su enfoque original, excepto solo por pasar el nombre del parámetro. La razón es que una vez que comienza a escribir esos procedimientos de ayuda, se convierte en un problema cuando todos comienzan a usar diferentes convenciones sobre cómo escriben los procedimientos de ayuda. Cuando alguien revisa su código, ahora tiene que verificarlo para asegurarse de que ha escrito el procedimiento de ayuda correctamente al depurar su código.

Sigue revisando cada argumento por separado, aunque tus dedos se cansan de escribir Grasshopper :) Tus seguidores te bendecirán cuando obtengan la inesperada ArgumentException y se guarden de una ejecución de depuración solo para determinar qué argumento falló.


Mi primer consejo para ti es conseguir ReSharper. Le dirá cuándo hay un problema de posibles valores nulos, y cuando no hay necesidad de verificarlos, y con el clic de un mouse se agregará la verificación. Una vez dicho esto...

Por lo general, no es necesario verificar las cadenas nulas y los enteros, a menos que esté recibiendo información de alguna fuente heredada.

Las cadenas se pueden verificar con string.IsNullOrEmpty () ...

Si aún decide que desea verificar todos y cada uno de los parámetros, puede usar el patrón de diseño de Comando y la reflexión, pero su código será innecesariamente torpe, o use lo siguiente y llámelo para cada método: private myType myMethod (cadena) param1, int param2, byte [] param3) {CheckParameters ("myMethod", {param1, param2, param3}); // resto de código ...

Y en tu clase de utilidad pon esto:

///<summary>Validates method parameters</summary> ///... rest of documentation public void CheckParameters(string methodName, List<Object> parameterValues) { if ( string.IsNullOrEmpty(methodName) ) throw new ArgumentException("Fire the programmer! Missing method name", "methodName")); Type t = typeof(MyClass); MethodInfo method = t.GetMethod(methodName); if ( method == null ) throw new ArgumentException("Fire the programmer! Wrong method name", "methodName")); List<ParameterInfo> params = method.GetParameters(); if ( params == null || params.Count != parameterValues.Count ) throw new ArgumentException("Fire the programmer! Wrong list of parameters. Should have " + params.Count + " parameters", "parameterValues")); for (int i = 0; i < params.Count; i++ ) { ParamInfo param = params[i]; if ( param.Type != typeof(parameterValues[i]) ) throw new ArgumentException("Fire the programmer! Wrong order of parameters. Error in param " + param.Name, "parameterValues")); if ( parameterValues[i] == null ) throw new ArgumentException(param.Name + " cannot be null"); } } // enjoy


Un enfoque que utilizo y que puede haber tomado de la fuente de NHibernate es crear una clase estática Guard , que se utiliza de la siguiente manera:

public void Foo(object arg1, string arg2, int arg3) { Guard.ArgumentNotNull(arg1, "arg1"); Guard.ArgumentNotNullOrEmpty(arg2, "arg2"); Guard.ArgumentGreaterThan(arg3, "arg3", 0); //etc. } public static class Guard { public static void ArgumentNotNull(object argument, string parameterName) { if (parameterName == null) throw new ArgumentNullException("parameterName"); if (argument == null) throw new ArgumentNullException(parameterName); } //etc. }

Esto reduce mucha de la paja al principio de los métodos y funciona bien.


Una pequeña mejora en la respuesta de Lou sería utilizar una tabla hash en su lugar, significa que comprueba los objetos y las cadenas. También es más fácil de rellenar y manejar en el método:

public static class ParameterChecker { public static void CheckForNull(Hashtable parameters) { foreach (DictionaryEntry param in parameters) { if (param.Value == null || string.IsNullOrEmpty(param.Value as string)) { throw new ArgumentNullException(param.Key.ToString()); } } } }

Como utilizarías como:

public User CreateUser(string userName, string password, string Email, string emailAlerts, string channelDescription) { var parameters = new Hashtable(); parameters.Add("Username", userName); parameters.Add("Password", password); parameters.Add("EmailAlerts", emailAlerts); parameters.Add("ChannelDescription", channelDescription); ParameterChecker.CheckForNull(parameters); // etc etc }


Y para los desarrolladores de C # 3.0 entre nosotros, una excelente manera de encapsular esta comprobación nula está dentro de un método de extensión.

public void Foo(string arg1, int? arg2) { arg1.ThrowOnNull(); arg2.ThrowOnNull(); } public static class extensions { public static void ThrowOnNull<T>(this T argument) where T : class { if(argument == null) throw new ArgumentNullException(); } }

Y si quisiera, siempre podría sobrecargar eso para tomar un nombre de argumento.