Ich bin auf diese Situation gestoßen. In der Tat, wie an anderer Stelle erwähnt, hat die BCL solche Fälle ... Ich werde versuchen, bessere Beispiele und einige Gründe zu liefern:
Wenn Sie eine bereits ausgelieferte Schnittstelle haben, die Sie aus Kompatibilitätsgründen aufbewahren und ...
Die Schnittstelle enthält Mitglieder, die veraltet oder unleserlich sind. Zum Beispiel BlockingCollection<T>.ICollection.SyncRoot
(unter anderem), während ICollection.SyncRoot
per se nicht veraltet ist, wird es werfen NotSupportedException
.
Die Schnittstelle enthält Elemente, von denen dokumentiert ist, dass sie optional sind und dass die Implementierung möglicherweise die Ausnahme auslöst. Zum Beispiel auf MSDN IEnumerator.Reset
dazu heißt es:
Die Rücksetzmethode wird für die COM-Interoperabilität bereitgestellt. Es muss nicht unbedingt implementiert werden. Stattdessen kann der Implementierer einfach eine NotSupportedException auslösen.
Aus Versehen sollte es sich bei der Gestaltung der Benutzeroberfläche in erster Linie um mehr als eine Benutzeroberfläche handeln. In BCL ist es ein gängiges Muster, schreibgeschützte Versionen von Containern mit zu implementieren NotSupportedException
. Ich habe es selbst gemacht, es ist das, was jetzt erwartet wird ... Ich kehre ICollection<T>.IsReadOnly
zurück, true
damit du es ihnen erzählen kannst. Das richtige Design wäre gewesen, eine lesbare Version der Schnittstelle zu haben, und dann wird die vollständige Schnittstelle von dieser übernommen.
Es gibt keine bessere Benutzeroberfläche. Ich habe zum Beispiel eine Klasse, mit der Sie über den Index auf Elemente zugreifen können. Überprüfen Sie, ob ein Element enthalten ist und in welchem Index es eine bestimmte Größe hat. Sie können es in ein Array kopieren. Es scheint ein Job zu sein, IList<T>
aber meine Klasse hat Eine feste Größe, und das Hinzufügen oder Entfernen wird nicht unterstützt, daher funktioniert es eher wie ein Array als wie eine Liste. Aber es gibt keine IArray<T>
in der BCL .
Die Schnittstelle gehört zu einer API, die auf mehrere Plattformen portiert ist, und bei der Implementierung einer bestimmten Plattform werden einige Teile davon nicht unterstützt. Im Idealfall gibt es eine Möglichkeit, dies zu erkennen, sodass portabler Code, der eine solche API verwendet, entscheiden kann, ob diese Teile aufgerufen werden oder nicht NotSupportedException
. Dies gilt insbesondere dann, wenn es sich um eine Portierung auf eine neue Plattform handelt, die im ursprünglichen Design nicht vorgesehen war.
Überlegen Sie auch, warum es nicht unterstützt wird?
Manchmal InvalidOperationException
ist eine bessere Option. Eine weitere Möglichkeit zum Hinzufügen von Polymorphismus in einer Klasse besteht beispielsweise darin, eine interne Schnittstelle auf verschiedene Weise zu implementieren, und Ihr Code wählt die zu instanziierende Schnittstelle in Abhängigkeit von den im Konstruktor der Klasse angegebenen Parametern aus. [Dies ist besonders nützlich, wenn Sie wissen, dass der Optionssatz feststeht und Sie nicht zulassen möchten, dass Klassen von Drittanbietern durch Abhängigkeitsinjektion eingeführt werden.] Ich habe dies getan, um ThreadLocal zurück zu portieren, da es sich um eine Tracking- und eine Nicht-Tracking-Implementierung handelt zu weit appart, und was wirkt sich ThreadLocal.Values
auf die Non-Tracking-Implementierung aus?InvalidOperationException
auch wenn es nicht vom Zustand des Objekts abhängt. In diesem Fall stellte ich die Klasse selbst vor und wusste, dass diese Methode implementiert werden musste, indem nur eine Ausnahme ausgelöst wurde.
Manchmal ist ein Standardwert sinnvoll. Zum Beispiel ist es aus den ICollection<T>.IsReadOnly
oben genannten Gründen sinnvoll, nur "wahr" oder "falsch" zurückzugeben, je nach Fall. Also ... was ist die Semantik von IFoo.Bar
? Möglicherweise gibt es einen sinnvollen Standardwert, der zurückgegeben werden muss.
Nachtrag: Wenn Sie die Kontrolle über die Benutzeroberfläche haben (und aus Kompatibilitätsgründen nicht bei dieser bleiben müssen), sollte es keinen Fall geben, in den Sie werfen müssen NotSupportedException
. Möglicherweise müssen Sie die Schnittstelle in zwei oder mehr kleinere Schnittstellen aufteilen, um die richtige Passform für Ihren Fall zu finden, was in Extremsituationen zu "Verschmutzung" führen kann.