2012-06-22 7 views
7

Ich habe eine Klasse mit einer Sammlung von Elementen. Der Einfachheit halber habe ich GetCurrentItem zur Verfügung gestellt, die vonErstellen einer Eigenschaft, die IndexOutOfRangeException auslösen kann

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

umgesetzt wird, die eine Ausnahme ausgelöst wird, wenn es keine Elemente in der Liste sind.

Sollte ich die Ausnahme ausgelöst haben oder sollte ich null zurückgeben? Wenn dies eine API wäre, die ich Ihnen ausgehändigt habe, was würden Sie erwarten? Die Ausnahme oder null? Gibt es einen besseren Weg, damit umzugehen?

+2

Welche die richtige API ist: 'Enumerable.Single' oder' Enumerable.SingleOrDefault'? (Antwort: es kommt darauf an) –

Antwort

9

Was ist richtiger? Wie Kirks Kommentar nahelegt: Es kommt darauf an. Manchmal macht ein null logischen Sinn und manchmal ist eine Ausnahme besser geeignet, wenn kein Standard vernünftig ist. Eine Sache, die ich versuche zu tun, ist zu denken "ruft GetCurrentItem einen logischen Fehler oder eine sichere Sache?"

Wenn es ein Fehler ist, GetCurrentItem aufzurufen, wenn keine vorhanden sind, dann ist das Auslösen einer Ausnahme der richtige Kurs. Wenn Ihre Sammlung z. B. eine HasCurrent oder IsEmpty Eigenschaft aufweist, bei der jemand das Ergebnis vor dem Aufruf von GetCurrentItem überprüfen könnte, dann sollten sie "es besser wissen". Aber wenn der aktuelle Artikel null ist eine korrekte logische Art der Verwendung Ihrer Klasse, dann auf alle Fälle Design es so. In jedem Fall dokumentiere ich das Verhalten in den Code-Kommentaren, um die Benutzer über das erwartete Verhalten zu informieren.

Ich werde dies jedoch sagen, die ArgumentOutOfRange Ausnahmebesonderung möglicherweise bluten Implementierungsdetails. Das heißt, wenn der Benutzer dieser Klasse keine Ahnung hat, dass die innere Struktur ein Array oder List<T> ist, blenden Sie diese Ausnahme nicht aus, sondern fangen Sie sie ein, wickeln Sie sie um und werfen Sie eine aussagekräftigere (benutzerdefinierte oder ähnliche) InvalidOperationException).

Da sie nicht wirklich direkt in einem Argument übergeben, bekommen sie eine ArgumentOutOfRange Ausnahme verwirrend :-) könnte

+0

Eine gute Wahl der Ausnahme ist 'InvalidOperationException', nach dem Beispiel von' Stack .Peek() '. –

+0

@MichaelLiu: Ja, einverstanden. Ich habe das in meiner Bearbeitung hinzugefügt, so wie du es gesagt hast :-) –

3

Lassen Sie es einen Fehler werfen. So funktionieren andere Kollektionen. Es sollte Sache der Benutzeranwendung sein, mit möglichen Ausnahmen umzugehen (besonders wenn mit Sammlungen gearbeitet wird). Es sollte vielleicht eine bool HasSelection() Methode sein, die der Benutzer aufrufen kann, bevor er fortfährt.

3

In Ausnahmefällen sollten Ausnahmen verwendet werden. Wenn CurrentItem null sein kann, sollten Sie keine Ausnahme auslösen. Ich sehe nicht, warum ein CurrentItem nicht außergewöhnlich ist.

1

Die Frage ist dann, ob Sie GetCurrentItem erwarten einen sicheren Wert zurückzukehren. Wenn Type nullfähig ist, sollte GetCurrentItem wahrscheinlich null zurückgeben, wenn kein aktuelles Element vorhanden ist. Wenn Sie immer erwarten, dass die Liste nicht leer ist und da immer etwas ausgewählt ist, werfen Sie eine sinnvolle Ausnahme ein.

Im Allgemeinen sollten Sie keine Ausnahme auslösen, es sei denn, Ihr Fall ist wirklich eine Ausnahme und kein normaler Anwendungsfall. Dies kann jedoch eher subjektiv sein.

0

Wenn dieses GetCurrentItem für Ihre API sinnvoll ist, würde ich "InvalidOperationException" auslösen, wenn keine Elemente vorhanden sind. Sie können es anders benennen, wenn Sie null als gültiges Ergebnis zulassen.

Überlegen Sie, ob die existierende LINQ Last Methode bereits dieselbe Funktionalität bietet.

1

Ich versuche, aus der Sicht eines Benutzers darüber nachzudenken. Gehen Sie für die Principal of Least Astonishment.

Wenn ich die Bibliothek oder das Objekt wurde mit und GetCurrentItem und ein IndexOutOfRangeException geworfen wurde genannt, würde ich denken: „Ich nicht mit einem Index etwas angerufen habe, wollte ich das aktuelle Element.“ Daher wäre mein Vorschlag, null zurückzugeben, was mich denken lassen würde: "Oh, es gibt keinen aktuellen Gegenstand."

Alternativ, wenn die Eigenschaft ein Indexer wäre und ich einen Artikel zu einem bestimmten Index bekommen wollte, würde mich eine IndexOutOfRangeException nicht überraschen.

Verwandte Themen