CA2208:Crear instancias de excepciones de argumentos correctamente

CA2208:Crear instancias de excepciones de argumentos correctamente

La regla de análisis de código CA2208 comprueba errores comunes al construir excepciones de argumento. Hay tres clases principales de excepciones de argumentos:ArgumentException, ArgumentNullException y ArgumentOutOfRangeException. Desafortunadamente, es fácil cometer un error al usarlos. Explicaré los errores comunes que CA2208 verifica y cómo solucionarlos (y cuándo suprimir la advertencia en su lugar).

Caso 1:paramName / mensaje se pasan en el orden incorrecto

Cuando pasa los parámetros de excepción de argumento en el orden incorrecto, recibirá una advertencia CA2208 como:

He aquí un ejemplo de este problema. El orden de los parámetros es (paramName, mensaje) y se pasan accidentalmente como (mensaje, paramName):

//Method signature
public ArgumentOutOfRangeException(string? paramName, string? message);

//Example of passing the parameters in the wrong order:
throw new ArgumentOutOfRangeException("Valid range: 100-999", nameof(id));
Code language: C# (cs)

Nota:para hacer las cosas más confusas, ArgumentException tiene el orden de parámetros opuesto (message, paramName).

La respuesta simple aquí es poner los argumentos en el orden correcto. Sin embargo, sugeriría usar argumentos con nombre en su lugar.

Cuando tiene dos parámetros del mismo tipo (cadena en este caso) uno al lado del otro, es muy fácil transponerlos accidentalmente como se muestra arriba. La mejor manera de protegerse contra este tipo de problema en general es acostumbrarse a usar argumentos con nombre (que hacen que el orden de los parámetros sea irrelevante). Este es un ejemplo de cómo crear una excepción de argumento con argumentos con nombre:

throw new ArgumentOutOfRangeException(message: "Valid range: 100-999", paramName: nameof(id));
Code language: C# (cs)

Pasar solo el nombre del parámetro a ArgumentException

ArgumentException no tiene una sobrecarga que acepte solo paramName , pero tiene uno que acepta solo mensaje . Cuando el compilador puede decir que estás pasando un nombre de parámetro para mensaje , informará la misma advertencia CA2208 que se muestra en la sección anterior. Aquí hay un ejemplo de lo que podría causar esto:

throw new ArgumentException(nameof(id));
Code language: C# (cs)

¿Es esto realmente un problema? Tu decides. Tal vez realmente desee pasar solo el nombre del parámetro de esta manera y desee deshacerse de la advertencia CA2208. En ese caso, puede suprimir CA2208 para esta línea de código:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 throw new ArgumentException(nameof(id));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)

Caso 2:paramName no coincide con los parámetros del método

Cuando pasa paramName a una excepción de argumento, el compilador verifica si coincide con el nombre de uno de los parámetros del método. Si no es así, haga coincidir, recibirá una advertencia CA2208 como esta:

Primero, si desea paramName para que coincida exactamente con el nombre del parámetro del método, sugiero usar el operador nameof() en lugar de codificar el nombre:

public Person Get(string uniqueId)
{
	throw new ArgumentNullException(paramName: nameof(uniqueId));
}
Code language: C# (cs)

En segundo lugar, supongamos que está usando intencionalmente el nombre de propiedad de un parámetro en lugar del nombre del parámetro. He aquí un ejemplo:

public void Post(Person person)
{
	throw new ArgumentNullException(paramName: nameof(person.FirstName));
}
Code language: C# (cs)

Está perfectamente bien lanzar una excepción de argumento para la propiedad de un parámetro como esta, y claramente paramName no coincidirá con el nombre del parámetro. En este caso, si realmente desea deshacerse de la advertencia CA2208, puede suprimirla en esta línea:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException(paramName: nameof(person.FirstName));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)

Caso 3:uso de un constructor sin parámetros

Cuando usa un constructor sin parámetros de excepción de argumento (es decir, nueva ArgumentException()), obtendrá una advertencia CA2208 como esta:

Si bien usar el constructor sin parámetros no es técnicamente incorrecto (después de todo, existe), en la mayoría de los casos probablemente tenga sentido pasar message / paramName para proporcionar información específica sobre la excepción.

Sin embargo, si decide que tiene más sentido usar el constructor sin parámetros y quiere deshacerse de la advertencia CA2208, puede suprimir CA2208 para esta línea:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException();
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)