Ein Mitarbeiter und ich haben das Verhalten des new
Schlüsselworts in C # untersucht, das für das Konzept des Versteckens gilt. Aus der Dokumentation :
Verwenden Sie den neuen Modifikator, um ein von einer Basisklasse geerbtes Element explizit auszublenden. Um ein geerbtes Element auszublenden, deklarieren Sie es in der abgeleiteten Klasse mit demselben Namen und ändern Sie es mit dem neuen Modifikator.
Wir haben die Dokumentation gelesen und verstehen, was es im Grunde tut und wie es es tut. Was wir nicht wirklich in den Griff bekommen konnten, ist, warum Sie es an erster Stelle tun müssten. Der Modifikator ist seit 2003 da und wir arbeiten beide schon länger mit .Net zusammen und es ist nie aufgetaucht.
Wann wäre dieses Verhalten in praktischer Hinsicht notwendig (z. B. auf einen Geschäftsfall bezogen)? Ist dies eine Funktion, die ihre Nützlichkeit überlebt hat, oder ist das, was sie macht, einfach ungewöhnlich genug in dem, was wir tun (insbesondere machen wir Webformulare und MVC-Anwendungen und einige WinForms und WPF mit kleinen Faktoren)? Wenn wir dieses Schlüsselwort ausprobierten und damit spielten, fanden wir einige Verhaltensweisen, die ein wenig gefährlich erscheinen, wenn sie missbraucht werden.
Das klingt ein wenig offen, aber wir suchen nach einem bestimmten Anwendungsfall, der auf eine Geschäftsanwendung angewendet werden kann, für die dieses spezielle Tool nützlich ist.
Antworten:
Sie können es verwenden, um die Kovarianz vom Rückgabetyp nachzuahmen. Eric Lipperts Erklärung . Eric liefert diesen Beispielcode:
Dies ist eine Problemumgehung.
public override Fish Contents() { ... }
ist nicht legal, obwohl sie sicher ist.Im Allgemeinen sollten Sie das Ausblenden von Methoden nicht verwenden, da dies für die Verbraucher Ihrer Klasse verwirrend ist (das obige spezifische Beispiel weist dieses Problem nicht auf). Nennen Sie Ihre neue Methode einfach etwas anderes, wenn Sie eine vorhandene Methode nicht überschreiben möchten.
In der Praxis ist es wahrscheinlich, dass Sie Methoden ausblenden müssen, wenn der Anbieter einer Basisklasse eine generische Methode hinzugefügt hat, die Sie bereits zu einer abgeleiteten Klasse hinzugefügt haben. Solch ein Programm kompiliert (und gibt Warnungen aus), ohne das neue Schlüsselwort, aber das Hinzufügen
new
sagt: "Ich weiß, dass meine Version dieser Methode die Version der Basisklasse ersetzt. Das ist schrecklich und verwirrend, aber wir bleiben dabei." Das ist immer noch besser, als die abgeleitete Klasse zu zwingen, ihre Methode umzubenennen.Nur zuzulassen, dass die abgeleitete Methode als Überschreibung behandelt wird, würde Probleme verursachen. Ohne Rücksicht auf die Implementierung des Compilers unterscheidet sich die neue Methode semantisch von der Basismethode, aber aufgrund des Polymorphismus wird die neue Methode aufgerufen, wenn Sie aufgefordert werden, eine Methode mit demselben Namen aufzurufen.
Diese Situation wird in diesem Beitrag von Eric Lippert ausführlich erörtert .
quelle
new
es ein Marker für "das ist schrecklich und verwirrend" ist.Ich denke, es ist da, falls Sie es brauchen, um etwas zu tun, woran die Sprachdesigner vielleicht nicht gedacht haben. C # war in vielerlei Hinsicht eine Reaktion auf frühe Versionen von Java. Und eine Sache, die Java getan hat, war, sehr explizit Entwickler in die Schublade zu stecken, um die Möglichkeit auszuschließen, dass Entwickler sich selbst in die Füße schießen. C # verfolgte einen etwas anderen Ansatz und gab den Entwicklern ein wenig mehr Kraft, um den Entwicklern mehr Möglichkeiten zu geben, sich selbst in die Füße zu schießen. Ein Beispiel ist das
unsafe
Schlüsselwort. Diesesnew
Schlüsselwort ist ein anderes.Nun, es ist wahrscheinlich nicht so nützlich wie,
unsafe
aber wenn Sie erst einmal in eine Sprachspezifikation geraten sind, ist es schwierig, aus einer Sprachspezifikation herauszukommen.quelle
Es sagt dem Leser, dass "ich die Implementierung dieser Methode durch die Basisklasse absichtlich versteckt habe" und nicht versehentlich.
quelle
Möglicherweise möchten Sie das vorherige Mitglied über einen anderen Namen verfügbar machen:
Prost.
quelle
Ich fand es sehr nützlich, wenn ich eine Testsuite für Legacy-Code erstellte. Es ermöglicht mir, externe Abhängigkeiten auszublenden, z. B. das Abfragen einer Datenbank innerhalb einer Methode, die von anderen Methoden verwendet wird. Um die anderen Methoden testen zu können, kann die ursprüngliche Logik, die von externen Ressourcen abhängt, ausgeblendet werden, ohne dass diesen Methoden in Testklassen das virtuelle Schlüsselwort hinzugefügt werden muss.
quelle