Stellen Sie sich vor, ich habe eine Funktion, die einen Fehler enthält:
Pseudocode:
void Foo(LPVOID o)
{
//implementation details omitted
}
Das Problem ist, dass der Benutzer die null
:
Object bar = null;
...
Foo(bar);
Dann wird die Funktion könnte wegen einer Zugriffsverletzung abstürzen; es kann aber auch passieren, dass sie gut funktioniert. Der Fehler besteht darin, dass die Funktion debe auf den ungültigen Fall der Übergabe von null
aber es hat einfach nicht geklappt. Es war nie ein Thema, weil man den Entwicklern zutraute, dass sie wussten, was sie taten.
Wenn ich nun die Funktion ändere in:
Pseudocode:
void Foo(LPVOID o)
{
if (o == null) throw new EArgumentNullException("o");
//implementation details omitted
}
dann werden Leute, die die Funktion gerne benutzt haben und zufällig keine Zugriffsverletzung erhalten haben, jetzt plötzlich eine EArgumentNullException
.
Soll ich weiterhin zulassen, dass Leute die Funktion missbräuchlich verwenden, und eine neue Version der Funktion erstellen? Oder verbessere ich die Funktion so, dass sie das enthält, was sie ursprünglich hätte enthalten sollen?
Und nun das moralische Dilemma. Wollen Sie immer neue Plausibilitätsprüfungen, Sicherheitsprüfungen und Assertions zu bestehendem Code hinzufügen? Oder rufen Sie die alte Funktion auf, die aufgegeben wurde, und haben eine neue?
Nehmen wir einen Fehler, der so häufig auftritt, dass Microsoft ihn für Entwickler beheben musste:
MessageBox(GetDesktopWindow, ...);
Nie und nimmer, immer ein Fenstermodell auf dem Desktop erstellen möchten. Sie werden das System sperren. Lassen Sie die Entwickler weiterhin den Computer des Benutzers sperren? Oder ändern Sie die Funktion in:
MessageBox(HWND hWndParent, ...)
{
if (hWndParent == GetDesktopWindow)
throw new Exception("hWndParent cannot be the desktop window. Use NULL instead.");
...
}
In Wirklichkeit hat Microsoft den Fenstermanager so geändert, dass der fehlerhafte Parameter automatisch korrigiert wird:
MessageBox(HWND hWndParent, ...)
{
if (hWndParent == GetDesktopWindow)
hWndParent = 0;
...
}
In meinem erfundenen Beispiel gibt es keine Möglichkeit, die Funktion zu patchen - wenn mir kein Objekt gegeben wurde, kann ich nicht tun, was ich an ihm tun muss.
Besteht die Gefahr, dass bestehender Code durch Hinzufügen einer Parametervalidierung beschädigt wird? Lassen Sie zu, dass der bestehende Code weiterhin falsch ist und falsche Ergebnisse liefert?