2012-06-22 5 views
7

Tengo una clase que contiene una colección de elementos. Para mayor comodidad que he proporcionado GetCurrentItem que se realiza medianteCrear propiedad que puede arrojar IndexOutOfRangeException

public Type GetCurrentItem 
{ 
    get { return this.items[this.items.Count - 1]; } 
} 

que será una excepción si no hay elementos en la lista.

¿Debo dejar que se emita la excepción o debo devolver null? Si esto fuera una API que te entregué, ¿qué esperarías? La excepción o nulo? ¿Hay una mejor manera de manejar esto?

+2

¿Qué es la API correcta: '' Enumerable.Single' o Enumerable.SingleOrDefault'? (respuesta: depende) –

Respuesta

9

¿Cuál es el más correcto? Como sugiere el comentario de Kirk: depende. A veces, un null tiene un sentido lógico y, a veces, una excepción es más adecuada si no es razonable. Una cosa que trato de hacer es pensar "¿Llamar al GetCurrentItem es una falla lógica o algo seguro?"

Si no se puede llamar al GetCurrentItem cuando no hay ninguno, lanzar una excepción es el curso correcto. Por ejemplo, si su colección tiene una propiedad HasCurrent o IsEmpty donde alguien podría examinar el resultado antes de llamar al GetCurrentItem, entonces deberían "saber mejor". Pero si el elemento actual es null es una forma lógica correcta de utilizar su clase, entonces, por supuesto, concéntrela de esa manera. De cualquier manera, documentaría el comportamiento en los comentarios del código para que los usuarios conozcan el comportamiento esperado.

Lo diré sin embargo, exponer la excepción ArgumentOutOfRange puede estar sangrando detalles de implementación. Es decir, si el usuario de esta clase no tiene idea de que la estructura interna es una matriz o List<T>, no desangre esa excepción, sino tómala, envuélvala y arroje una más significativa (personalizada o similar InvalidOperationException).

ya que no está pasando realmente directamente en una discusión, ellos recibiendo una excepción ArgumentOutOfRange podría ser confuso :-)

+0

Una buena opción de excepción es 'InvalidOperationException', siguiendo el ejemplo establecido por' Stack .Peek() '. –

+0

@MichaelLiu: Sí, de acuerdo. Estaba agregando eso en mi edición tal como lo comenté :-) –

3

Déjalo arrojar un error. Así es cómo funcionan otras colecciones. Debería corresponder a la aplicación del usuario manejar las posibles excepciones (especialmente cuando se trabaja con colecciones). Tal vez debería haber un método bool HasSelection() que el usuario puede llamar antes de continuar.

3

Las excepciones se deben utilizar para casos excepcionales. Si CurrentItem puede ser nulo, no debe lanzar una excepción. No veo por qué no tener un CurrentItem es excepcional.

1

La pregunta entonces es si usted espera GetCurrentItem para devolver un valor seguro. Si Type es anulable, entonces GetCurrentItem probablemente devuelva null cuando no hay un elemento actual. Si siempre espera que la lista no esté vacía y que siempre haya algo seleccionado por defecto, genere una excepción significativa.

Por lo general, no debe lanzar una excepción a menos que su caso sea realmente una excepción y no un caso de uso normal. Sin embargo, esto puede ser bastante subjetivo.

0

Si este GetCurrentItem tiene sentido para su API, lanzaría "InvalidOperationException" cuando no hay elementos. Es posible que desee nombrarlo de manera diferente si permite un resultado nulo como válido.

Considere si el método existente LINQ Last ya ofrece la misma funcionalidad.

1

Intento pensarlo desde la perspectiva de un usuario. Vaya por el Principal of Least Astonishment.

Si estaba usando la biblioteca u objeto y llamé al GetCurrentItem y me arrojaron IndexOutOfRangeException, pensaría: "No llamé a nada con un índice, quería el artículo actual". Por lo tanto, mi sugerencia sería devolver nulo, lo que me haría pensar, "Oh, no hay ningún elemento actual".

Alternativamente, si la propiedad fuera un indexador y quisiera obtener un artículo en cierto índice, no me sorprendería un IndexOutOfRangeException.

Cuestiones relacionadas