Por lo que he visto, las ArgumentExceptions generalmente se usan así:
public void UpdateUser(User user) { if (user == null) throw new ArgumentException("user"); // etc... }pero que pasa si tengo algo como esto:
public void UpdateUser(int idOfUser) { var user = GetUserById(idOfUser); if (user == null) throw new ArgumentException("idOfUser"); // etc... } ¿Sigue siendo una ArgumentException ?
El primero
if (user == null) throw new ArgumentException("user");debiera ser
if (user == null) throw new ArgumentNullException("user"); Si es posible, no debe lanzar ArgumentException directamente
Las principales clases derivadas de
ArgumentExceptionsonArgumentNullExceptionyArgumentOutOfRangeException. Estas clases derivadas deben usarse en lugar deArgumentException, excepto en situaciones en las que ninguna de las clases derivadas es aceptable.
Para el segundo ejemplo, aquí ¿Debo lanzar una excepción KeyNotFoundException para una búsqueda en la base de datos? sugieren (en comentarios)
if (user == null) throw new ObjectNotFoundException(); Se define en System.Data : System.Data.ObjectNotFoundException .
Como sugiere el nombre, una ArgumentException es una excepción sobre un argumento. Significa que el argumento era de alguna manera intrínsecamente incorrecto.
La forma general es:
public void SomeMethod(SomeType arg) { if(!TestArgValid(arg)) throw new ArgumentException("arg"); //Or more specific is possible //eg ArgumentNullException /* Actually do stuff */ } Si la única forma posible de que GetUserById pudiera fallar fuera que hubiera algo intrínsecamente incorrecto con el valor de idOfUser , entonces lo siguiente sería lo mismo en la práctica:
public void UpdateUser(int idOfUser) { if(!TestValid(idOfUser)) throw new ArgumentException("idOfUser"); var user = GetUserById(idOfUser); // Do stuff with user } public void UpdateUser(int idOfUser) { var user = GetUserById(idOfUser); if(user == null) throw new ArgumentException("idOfUser"); // Do stuff with user } Y si por alguna razón resultó ser más rápido o menos derrochador de algún recurso para probar user después del hecho que idOfUser antes del hecho y si no hubo efectos secundarios de llamar a GetUserById , y si la diferencia realmente importaba, entonces tal vez el segundo versión sería una optimización razonable de la primera.
Pero eso solo se cumple si todos los if anteriores se cumplen, y entonces es una forma extraña de detectar un argumento inválido que tiene alguna ventaja específica en la que nos beneficiamos de la encapsulación de métodos al ocultar esa rareza de todo lo demás.
Lo más probable es que pueda haber un idOfUser válido para el que no haya un user correspondiente, en cuyo caso ciertamente no fue una excepción de argumento.