Der einzige Grund, an den ich denken kann, ist, dass Sie manchmal geschützte Methoden schreiben müssen, um andere geschützte Methoden zu überschreiben. Die Sprache könnte wurde entworfen, um dies zu ermöglichen:
%Vor%aber nicht das
%Vor% aber das könnte etwas schwierig zu folgen sein - es ist die Abwesenheit von override
, die es nutzlos macht, während im Falle von
es ist die Präsenz von virtual
, die nutzlos ist. Das Vorhandensein von etwas "falschem" ist wahrscheinlich leichter zu verstehen als das Fehlen von etwas Nützlichem.
In diesem Fall kann es auch Auswirkungen auf die Performance haben, virtuell zu sein, während das Schützen von etwas statt des Privaten das wahrscheinlich nicht tut - also ist es ein bisschen schwerer.
Das sind aber nur Vermutungen - wenn wir wirklich Glück haben, wird Eric Lippert eine definitive Antwort geben. Er ist derjenige, den du willst, nicht ich:)
Beste Antwort: Warnungen als Fehler behandeln und sie sind gleichwertig;)
virtuell wird verwendet, um eine Methode / Eigenschaft "override" zu deklarieren. fähig ".
sealed wird verwendet, um anzugeben, dass die Klasse nicht geerbt werden kann.
Eine virtuelle Methode in einer versiegelten Klasse kann daher niemals außer Kraft gesetzt werden, da die Klasse niemals vererbt werden kann. Es macht einfach keinen Sinn.
protected beeinträchtigt den Zugriff auf ein Mitglied, deklariert es nicht "override-fähig" wie virtuell (obwohl es oft auf diese Weise verwendet wird) und ist dementsprechend nicht widersprüchlich.
Ich kann keinen guten Grund dafür sehen. Das geschützte MyMethod kann von MyClass aufgerufen werden, wird aber nie von einer abgeleiteten Klasse aufgerufen (weil MyClass versiegelt ist). Die virtuelle Version kann auch direkt von MyClass aufgerufen werden. Es ist jedoch unzulässig, dass die Methode überschrieben wird, weil Sie keine Klasse aus MyClass ...
ableiten könnenEine versiegelte Klasse kann über Vererbung geschützte Mitglieder haben. Wenn eine Methode Teil einer Klasse ist, spielt es keine Rolle, wie diese Methode dorthin gelangt.
Im ersten Fall ist es mit der protected-Methode für die versiegelte Klasse genauso, als ob die versiegelte Klasse eine geschützte Methode geerbt hätte. Also kompiliert es.
Aus Neugier, was genau ist die Warnung gegeben?
Der Fehler ist:
CS0549: 'Funktion' ist ein neues virtuelles Mitglied in der versiegelten Klasse 'class'.
Erstens macht es trotz der Tatsache, dass es nicht wirklich Sinn macht, neue protected
oder virtual
Mitglieder in eine sealed
Klasse aufzunehmen, das CLI¹ es erlaubt. Die CLI ermöglicht auch das Aufrufen von Mitgliedern einer versiegelten Klasse mit der Anweisung callvirt
IL, auch wenn ein Compiler sie durch die Anweisung call
ersetzen könnte.
Zur Zeit kann ich in ECMA-334 (C # -Sprachspezifikation) nichts finden, für das der Compiler den obigen Fehler ausgeben muss. Es sieht so aus, als ob eine Microsoft-Implementierung den Fehler hinzugefügt hat, nur weil es nicht sinnvoll ist, neue virtuelle Member in eine versiegelte Klasse aufzunehmen.
¹Die CLI ist eine virtuelle Maschine, und der C # -Compiler gibt Bytecode aus, der darauf ausgeführt wird. Fast jedes Konzept, das in der CLI illegal ist, ist aus diesem Grund auch in C # illegal - aber das ist ein Fall, in dem C # ein wenig mehr tut (nicht dass es ein Problem ist).
Edit: Es scheint, dass Posts, die markiert werden, erklären, warum es keinen Sinn macht , Code wie den im OP zu schreiben. Aber bezüglich der Regel, die es zu einem Compilerfehler gemacht hat, scheinen sie falsch zu sein.
Eine versiegelte Klasse kann nicht unterklassifiziert werden, daher ist virtuell keine Option. Also Fehler.
Das erste ist ein bisschen albern aber gültig, also warnt es.
Als versiegelt When applied to a class, the sealed modifier prevents other classes from inheriting from it.
hier versuche ich euch eins nach dem anderen zu erklären:
%Vor% es gibt Ihnen eine Warnung, weil es praktisch keinen Sinn macht, denn nachdem Sie eine Klasse als versiegelt deklariert haben, können Sie sie nicht erben und Ihre Methode ist protected
, so dass Sie nicht außerhalb der Klasse mit ihrem Objekt darauf zugreifen können (und behalten Beachten Sie auch, dass Sie keine untergeordnete Klasse erstellen können, so dass Sie diese Methode auch nicht mit diesem Trick verwenden können.) So macht es praktisch keinen Sinn protected
zu machen, damit der Compiler Sie warnt, aber wenn Sie es machen es als public
oder internal
dann gibt es keinen Fehler, weil es in diesem Fall nützlich ist.
jetzt der zweite:
%Vor% Wie Sie Ihre Klasse versiegelt haben und nun machen Sie Ihre Methode so virtuell, dass Sie indirekt jemandem ein Angebot zum Überschreiben geben, und das kann nur durch Vererbung möglich sein und hier kommt das Problem. Ihre Klasse ist also versiegelt kann mit dieser Klasse keine Vererbung durchführen. Deshalb gibt es mit virtual
einen Fehler.
Ich hoffe, es wird Ihnen helfen, zu verstehen.
als Referenz Ссылка
Wenn ein neues geschütztes Member deklariert wird, bedeutet dies, dass dieses Member mit untergeordneten Klassen geteilt werden soll. Eine versiegelte Klasse kann keine Nachkommen haben. Ein neues geschütztes Mitglied zu deklarieren ist also ein bisschen ein Oxymoron, genauso wie es eine neue virtuelle Methode in einer versiegelten Klasse deklariert.
Warum virtual einen Fehler erzeugt, während protected nur eine Warnung erzeugt, kann ich nur spekulieren, dass es vielleicht damit zu tun hat, dass neue virtuelle Methoden es erfordern, dass der Compiler Datenstrukturen für den Typ (eine vtable) erstellt Neue geschützte Mitglieder haben nur ein Zugriffs-Flag gesetzt - keine neue Datenstruktur. Wenn der Compiler keine vtable für eine versiegelte Klasse erstellen darf, was sollte er tun, wenn er auf eine neue virtuelle Methode trifft? Fehler beim Kompilieren Eine neue geschützte Methode in einer versiegelten Klasse ist sinnlos, erfordert jedoch nicht, dass der Compiler in verbotenes Gebiet vordringt.