Ich habe gesehen, dass beide Begriffe in verschiedenen Online-Erklärungen fast synonym verwendet werden, und die meisten Lehrbücher, die ich konsultiert habe, sind sich auch nicht ganz klar über die Unterscheidung.
Gibt es vielleicht eine klare und einfache Möglichkeit, den Unterschied zu erklären, den ihr kennt?
Typkonvertierung (manchmal auch als Typumwandlung bezeichnet )
So verwenden Sie einen Wert eines Typs in einem Kontext, der einen anderen erwartet.
Nicht konvertierender Typ Cast (manchmal auch als Typ Wortspiel bekannt )
Eine Änderung, die die zugrunde liegenden Bits nicht ändert.
Zwang
Prozess, bei dem ein Compiler automatisch einen Wert eines Typs in einen Wert eines anderen Typs konvertiert, wenn dieser zweite Typ vom umgebenden Kontext benötigt wird.
Antworten:
Typkonvertierung :
Zwang ist also implizit, Besetzung ist explizit und Bekehrung ist eine davon.
Einige Beispiele (aus derselben Quelle ):
Zwang (implizit):
Besetzung (explizit):
quelle
Die Verwendung variiert, wie Sie bemerken.
Meine persönlichen Verwendungen sind:
Eine "Besetzung" ist die Verwendung eines Besetzungsoperators . Ein Cast-Operator weist den Compiler an, dass entweder (1) dieser Ausdruck nicht vom angegebenen Typ ist, aber ich verspreche Ihnen, dass der Wert zur Laufzeit von diesem Typ sein wird; Der Compiler behandelt den Ausdruck als vom angegebenen Typ, und die Laufzeit erzeugt einen Fehler, wenn dies nicht der Fall ist, oder (2) der Ausdruck ist vollständig vom anderen Typ, es gibt jedoch eine bekannte Möglichkeit, Instanzen zuzuordnen vom Typ des Ausdrucks mit Instanzen des Cast-to-Typs. Der Compiler wird angewiesen, Code zu generieren, der die Konvertierung durchführt. Der aufmerksame Leser wird feststellen, dass dies Gegensätze sind, was ich für einen ordentlichen Trick halte.
Eine "Konvertierung" ist eine Operation, bei der ein Wert eines Typs als Wert eines anderen Typs behandelt wird - normalerweise ein anderer Typ, obwohl eine "Identitätskonvertierung" technisch gesehen immer noch eine Konvertierung ist. Die Konvertierung kann "Repräsentationsänderung" sein, wie "int" zu "double", oder "Repräsentationserhaltung" wie "Zeichenfolge zu Objekt". Konvertierungen können "implizit" sein, für die keine Besetzung erforderlich ist, oder "explizit", für die eine Besetzung erforderlich ist.
Ein "Zwang" ist eine repräsentationsverändernde implizite Umwandlung.
quelle
Data.Coerce.coerce :: Coercible a b => a -> b
funktioniert für Typen, die nachweislich die gleiche Repräsentation haben;Unsafe.Coerce.unsafeCoerce :: a -> b
funktioniert für zwei beliebige Typen (und lässt Dämonen aus der Nase kommen, wenn Sie es falsch verwenden).Casting ist der Prozess, bei dem Sie einen Objekttyp als einen anderen Typ behandeln. Coercing konvertiert ein Objekt in ein anderes.
Beachten Sie, dass im vorherigen Prozess keine Konvertierung erforderlich ist. Sie haben einen Typ, den Sie als einen anderen behandeln möchten. Angenommen, Sie haben 3 verschiedene Objekte, die von einem Basistyp erben, und Sie haben eine Methode, die dies übernimmt Basistyp: Wenn Sie jetzt den spezifischen untergeordneten Typ verwenden, können Sie ihn zu dem, was er ist, in CAST umwandeln und alle spezifischen Methoden und Eigenschaften dieses Objekts verwenden. Dadurch wird keine neue Instanz des Objekts erstellt.
Auf der anderen Seite impliziert das Erzwingen die Erstellung eines neuen Objekts im Speicher des neuen Typs, und dann wird der ursprüngliche Typ in den neuen kopiert, wobei beide Objekte im Speicher verbleiben (bis die Garbage Collectors eines oder beide entfernen). .
quelle
Beim Casting bleibt die Art der Objekte erhalten. Zwang nicht.
Zwang nimmt den Wert eines Typs, der NICHT zuweisungskompatibel ist, und konvertiert ihn in einen Typ, der zuweisungskompatibel ist. Hier
Int32
mache ich einen Zwang, weil er NICHT vonInt64
... erbt, also ist er NICHT zuweisungskompatibel. Dies ist ein zunehmender Zwang (keine Daten verloren). Ein zunehmender Zwang ist eine implizite Bekehrung . Ein Zwang führt eine Konvertierung durch.Mit Casting können Sie einen Typ so behandeln, als wäre er von einem anderen Typ, während Sie den Typ beibehalten .
Quelle: The Common Language Infrastructure Annotated Standard von James S. Miller
Was jetzt seltsam ist, ist, dass die Microsoft-Dokumentation zu Casting nicht mit der ecma-335-Spezifikationsdefinition von Casting übereinstimmt.
... Das klingt nach Zwang ohne Casting.
Beispielsweise,
Wer weiß? Vielleicht prüft Microsoft, ob jemand dieses Zeug liest.
quelle
Unten ist ein Beitrag aus dem folgenden Artikel :
Der Unterschied zwischen Zwang und Gießen wird oft vernachlässigt. Ich kann sehen warum; Viele Sprachen haben für beide Operationen dieselbe (oder eine ähnliche) Syntax und Terminologie. Einige Sprachen bezeichnen eine Konvertierung möglicherweise sogar als "Casting". Die folgende Erklärung bezieht sich jedoch auf Konzepte im CTS.
Wenn Sie versuchen, einem Speicherort eines anderen Typs einen Wert eines bestimmten Typs zuzuweisen, können Sie einen Wert des neuen Typs generieren, der eine ähnliche Bedeutung wie das Original hat. Das ist Zwang. Mit Zwang können Sie den neuen Typ verwenden, indem Sie einen neuen Wert erstellen, der in gewisser Weise dem Original ähnelt. Einige Zwänge verwerfen möglicherweise Daten (z. B. Konvertieren des int 0x12345678 in den kurzen 0x5678), andere möglicherweise nicht (z. B. Konvertieren des int 0x00000008 in den kurzen 0x0008 oder des langen 0x0000000000000008).
Denken Sie daran, dass Werte mehrere Typen haben können. Wenn Ihre Situation etwas anders ist und Sie nur einen anderen Werttyp auswählen möchten, ist das Casting das Werkzeug für den Job. Das Casting zeigt lediglich an, dass Sie einen bestimmten Typ bearbeiten möchten, den ein Wert enthält.
Der Unterschied auf Codeebene variiert von C # bis IL. In C # sehen Casting und Zwang ziemlich ähnlich aus:
Auf IL-Ebene sind sie ganz anders:
In Bezug auf die logische Ebene gibt es einige wichtige Unterschiede. Was am wichtigsten ist, ist, dass Zwang einen neuen Wert schafft, Casting jedoch nicht. Die Identität des ursprünglichen Werts und der Wert nach dem Gießen sind gleich, während sich die Identität eines erzwungenen Werts vom ursprünglichen Wert unterscheidet. Durch das Zusammenwirken wird eine neue, eindeutige Instanz erstellt, durch das Casting jedoch nicht. Eine Konsequenz ist, dass das Ergebnis des Castings und des Originals immer gleichwertig sind (sowohl in Bezug auf Identität als auch in Bezug auf Gleichheit), aber ein erzwungener Wert kann gleich oder nicht gleich dem Original sein und niemals die ursprüngliche Identität teilen.
Die Auswirkungen von Zwang sind in den obigen Beispielen leicht zu erkennen, da die numerischen Typen immer nach Wert kopiert werden. Bei der Arbeit mit Referenztypen wird es etwas schwieriger.
Im folgenden Beispiel ist eine Konvertierung eine Besetzung, während die andere ein Zwang ist.
Nach diesen Konvertierungen sind Tupel und Name gleich, aber Zeichenfolgen sind nicht gleich. Sie könnten die Situation etwas verbessern (oder etwas verwirrender), indem Sie Equals () und operator == () in der Name-Klasse implementieren, um einen Namen und eine Zeichenfolge [] zu vergleichen. Diese Operatoren würden das Vergleichsproblem "beheben", aber Sie hätten immer noch zwei separate Instanzen. Änderungen an Zeichenfolgen werden nicht in Namen oder Tupeln wiedergegeben, während Änderungen an Namen oder Tupeln in Namen und Tupel wiedergegeben werden, jedoch nicht in Zeichenfolgen.
Obwohl das obige Beispiel einige Unterschiede zwischen Gießen und Zwang veranschaulichen sollte, dient es auch als gutes Beispiel dafür, warum Sie bei der Verwendung von Konvertierungsoperatoren mit Referenztypen in C # äußerst vorsichtig sein sollten.
quelle
Aus dem CLI-Standard :
quelle
Laut Wikipedia
Der Unterschied zwischen Typguss und Typzwang ist wie folgt:
Hinweis : Casting ist keine Konvertierung. Es ist nur der Prozess, mit dem wir einen Objekttyp als einen anderen Typ behandeln. Daher wird der tatsächliche Objekttyp sowie die Darstellung während des Gießens nicht geändert.
Ich stimme den Worten von @ PedroC88 zu:
quelle