Los MSDN guidelines for standard exceptions estados:
hacer en el valor de uso para el nombre del parámetro de valor implícito de propiedad set.
El siguiente ejemplo de código muestra una propiedad que arroja una excepción si la persona que llama pasa un argumento nulo.
public IPAddress Address
{
get
{
return address;
}
set
{
if(value == null)
{
throw new ArgumentNullException("value");
}
address = value;
}
}
Además, el MSDN guidelines for property design dicen:
evitar tirar excepciones a captadores de propiedad.
Los captadores de propiedades deben ser operaciones simples sin ningún requisito previo. Si un getter puede arrojar una excepción, considere rediseñar la propiedad a sea un método. Esta recomendación no se aplica a los indexadores . Los indexadores pueden arrojar excepciones debido a argumentos no válidos.
Es válido y aceptable lanzar excepciones de un establecimiento de propiedades.
Así que suelta ArgumentNullException
en el organismo en null
y ArgumentException
en la cadena vacía, y no hacer nada en el captador. Como el colocador lanza y solo usted tiene acceso al campo de respaldo, es fácil asegurarse de que no contenga un valor no válido. Tener el tiro de getter es inútil. Sin embargo, este podría ser un buen lugar para usar Debug.Assert
.
Si realmente no puede proporcionar un valor por defecto, entonces supongamos que tiene tres opciones:
sólo devuelve lo que haya en la propiedad y documentar este comportamiento como parte del contrato de uso. Deja que la persona que llama lidie con eso. También podría exigir un valor válido en el constructor. Sin embargo, esto podría ser completamente inapropiado para su aplicación.
Reemplazar la propiedad por métodos: un método setter que arroja cuando pasa un valor no válido, y un método getter que arroja InvalidOperationException
cuando nunca se le asignó un valor válido a la propiedad.
Tirar InvalidOperationException
del comprador, ya que podría considerar 'la propiedad nunca ha sido asignada' a un estado no válido. Si bien no debería tirar normalmente desde getters, supongo que esta podría ser una buena razón para hacer una excepción.
Si elige las opciones 2 o 3, también debe incluir un método que devuelve un TryGet- bool
que indica si la propiedad se ha establecido en un valor válido, y si es así devuelve ese valor en un parámetro out
. De lo contrario, obligará a las personas que llaman a estar preparadas para manejar un InvalidOperationException
, a menos que hayan establecido previamente la propiedad ellos mismos y así sepan que no lanzará. Comparar int.Parse
versus int.TryParse
.
Sugeriría usar la opción 2 con el método TryGet. No infringe ninguna de las pautas e impone requisitos mínimos sobre el código de llamada.
Sobre las otras sugerencias
ApplicationException
es demasiado general. ArgumentException
es un poco demasiado general para null
, pero está bien si no.MSDN docs again:
arroje la (la más derivada) excepción más específica que es apropiado. Por ejemplo, si un método recibe un valor nulo (Nothing en Visual básico) argumento, se debe lanzar System.ArgumentNullException lugar de su System.ArgumentException tipo base .
De hecho no se debe utilizar en absoluto ApplicationException
(docs):
No derivan excepciones personalizadas de la T: Clase System.Exception en lugar de la T: Clase System.ApplicationException.
Originalmente se pensó que las excepciones personalizados deben derivar de la clase ApplicationException; sin embargo, esto no se ha encontrado para agregar un valor significativo. Para obtener más información, vea las Mejores prácticas para manejar excepciones.
InvalidOperationException
está destinado no para cuando los argumentos a un método o propiedad no son válidos, pero para cuando la operación como un todo no es válido (docs). No se debe tirar del colocador:
Haz lanzar una excepción System.InvalidOperationException si en un estado inadecuado. System.InvalidOperationException debe lanzarse si un conjunto de propiedades o una llamada a un método no son apropiados dado el estado actual del objeto. Por ejemplo, escribir en un System.IO.FileStream que se haya abierto para leer debería arrojar una excepción System.InvalidOperationException.
Por cierto, InvalidOperationException
es para cuando la operación no es válida para el estado actual del objeto. Si la operación es siempre válido para toda la clase, se debe utilizar NotSupportedException
.
Toma en cuenta también las propiedades son métodos azucaradas sintácticas. – Dykam
Una discusión interesante relacionada: http://stackoverflow.com/questions/1488472/best-practices-throwing-exceptions-from-properties – Joren