reference-type

___ answer3656129 ___

String ist ein Referenztyp, kein Werttyp. In vielen Fällen kennen Sie die Länge der Zeichenfolge und den Inhalt der Zeichenfolge. In solchen Fällen ist es einfach, den Speicher für die Zeichenfolge zuzuordnen. aber bedenke so etwas.

%Vor%

ist es nicht möglich, die Zuordnungsdetails für "s" in der Kompilierungszeit zu kennen. Der Benutzer gibt die Werte ein und alle eingegebenen Zeichenfolgen / Zeilen werden in den s gespeichert. Daher werden Zeichenfolgen im Heapspeicher gespeichert, sodass der Speicher neu zugewiesen wird, damit er in den Inhalt der Zeichenfolge s passt. Und der Verweis auf diese Zeichenfolge wird im Stapel gespeichert.

Um mehr zu erfahren, lesen Sie bitte: .net zero by petzold

Lesen: Garbage Collection von CLR Via C # für Zuordnungsdetails auf Stapel.

Bearbeiten: Console.WriteLine (); zu Console.ReadLine ();

    
___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ tag123string ___ Eine Zeichenfolge ist eine endliche Abfolge von Symbolen, die üblicherweise für Text verwendet wird, manchmal jedoch auch für beliebige Daten. ___ answer3660144 ___

Zusätzlich zu den Gründen von Dan:

Werttypen sind nach Definition solche Typen, die ihre Werte in sich selbst speichern, anstatt auf einen Wert anderswo zu verweisen. Deshalb werden Werttypen als "Werttypen" und Referenztypen als "Referenztypen" bezeichnet. Also ist Ihre Frage wirklich "Warum bezieht sich eine Zeichenkette auf ihren Inhalt und nicht einfach auf mit Inhalt?"

Das liegt daran, dass Werttypen die nette Eigenschaft haben, dass jede Instanz eines bestimmten Werttyps dieselbe Größe im Speicher hat.

Na und? Warum ist das eine schöne Eigenschaft? Angenommen, Zeichenfolgen waren Werttypen, die eine beliebige Größe haben könnten, und berücksichtigen Folgendes:

%Vor%

Was sind die ursprünglichen Inhalte dieses Arrays aus drei Strings? Für Werttypen gibt es kein "Null". Daher ist es sinnvoll, ein Array aus drei leeren Strings zu erstellen. Wie würde das in Erinnerung bleiben? Denken Sie ein bisschen darüber nach. Wie würdest du es tun?

Nehmen wir an, Sie sagen

%Vor%

Jetzt haben wir "", "Hallo" und "" im Array. Wo im Speicher ist das "Hallo"? Wie groß ist der Slot, der für mistrings [1] vergeben wurde? Der Speicher für das Array und seine Elemente muss irgendwo sein.

Damit bleibt der CLR die folgende Auswahl:

  • Größe ändern das Array jedes Mal, wenn Sie eines seiner Elemente ändern, kopieren Sie das gesamte Ding, das Megabyte in der Größe
  • sein könnte
  • verbieten das Erstellen von Arrays mit Werttypen unbekannter Größe
  • verbieten das Erstellen von Werttypen unbekannter Größe

Das CLR-Team wählte das letztere. Wenn Sie Strings zu Referenztypen machen, können Sie Arrays effizient erstellen.

    
___ qstntxt ___

Warum ist string ein Referenztyp, obwohl er normalerweise primitiver Datentyp wie int, float oder double ist.

    
___ tag123primitivetipes ___ Eingebettete Typen in einer beliebigen Programmiersprache, die axiomatisch definiert sind und nicht in andere Typen in der Sprache unterteilt werden können. ___ answer3655991 ___

Huch, diese Antwort wurde akzeptiert und dann habe ich sie geändert. Ich sollte wahrscheinlich die ursprüngliche Antwort an den unteren Rand einfügen, da dies vom OP akzeptiert wurde.

Neue Antwort

Aktualisieren : Hier ist die Sache. %code% absolut muss sich wie ein Referenztyp verhalten . Die Gründe dafür wurden bisher von allen Antworten berührt: Der %code% -Typ hat keine konstante Größe, es macht keinen Sinn, den gesamten Inhalt einer Zeichenkette von einer Methode in eine andere zu kopieren, sonst würden %code% -Arrays muss die Größe von themelves ändern - um nur einige zu nennen.

Aber Sie könnten definieren %code% als %code% , das intern auf ein %code% -Array verweist, oder sogar einen %code% -Zeiger und ein %code% für seine Länge, machen Sie es unveränderlich, und voila! , Sie hätten einen Typ, der sich wie ein Referenztyp verhält, aber technisch ein Werttyp ist.

Das wäre ziemlich albern, ehrlich gesagt. Wie Eric Lippert in einigen der Kommentare zu anderen Antworten darauf hingewiesen hat, ist die Definition eines solchen Werttyps im Grunde dasselbe wie die Definition eines Referenztyps. In fast jeder Hinsicht wäre es von einem auf die gleiche Weise definierten Referenztyp nicht zu unterscheiden.

Also die Antwort auf die Frage "Warum ist %code% ein Referenztyp?" ist im Grunde genommen: "Es Wert zu machen wäre einfach albern." Aber wenn das der einzige Grund ist, dann ist die logische Schlussfolgerung, dass %code% tatsächlich wie oben beschrieben als %code% definiert werden konnte und es kein besonders gutes Argument gegen diese Wahl geben würde.

Allerdings sind Gründe, dass es besser ist, %code% a %code% als% %code% zu machen, die mehr als rein intellektuell sind. Hier sind ein Paar, an das ich denken konnte:

Um das Boxen zu verhindern

Wenn %code% ein Werttyp wäre, dann müsste jedes Mal, wenn Sie es an eine Methode übergeben haben, die %code% erwartet, ein neues %code% erzeugt werden, wodurch der Heap aufgebläht würde und sinnlos wäre GC-Druck. Da Strings im Prinzip überall sind , wäre es ein großes Problem, sie zu haben, wenn man sie ständig boxt.

Für einen intuitiven Gleichheitsvergleich

Ja, %code% kann %code% überschreiben, unabhängig davon, ob es sich um einen Referenztyp oder -typ handelt. Aber wenn es ein Werttyp wäre, dann würde %code% false zurückgeben! Dies liegt daran, dass beide Argumente eingerahmt und die Argumente mit Box nie erhalten würden habe gleiche Referenzen (soweit ich weiß).

Auch wenn es wahr ist, dass Sie einen Wertetyp definieren könnten, um genau wie einen Referenztyp zu verwenden, indem er aus einem einzelnen Referenztypfeld besteht, wäre es immer noch nicht genau das gleiche. Also behalte ich dies als den vollständigeren Grund, warum %code% ein Referenztyp ist: Sie könnten es zu einem Werttyp machen, aber dies würde es nur mit unnötigen Schwächen belasten.

Ursprüngliche Antwort

Es ist ein Referenztyp, weil nur Referenzen darauf herumgereicht werden.

Wenn es ein Werttyp wäre, dann würde jedes Mal, wenn Sie eine Zeichenfolge von einer Methode zu einer anderen übergeben, die gesamte Zeichenfolge kopiert werden *.

Da es ein Referenztyp ist, anstelle von String-Werten wie "Hallo Welt!" herumgereicht werden - "Hallo Welt!" ist übrigens 12 Zeichen, was bedeutet, dass es (mindestens) 24 Bytes Speicher benötigt - nur Referenzen zu diesen Strings werden weitergegeben. Das Übergeben einer Referenz ist viel billiger als das Übergeben jedes einzelnen Zeichens in einer Zeichenfolge.

Außerdem ist es wirklich nicht ein normaler primitiver Datentyp. Wer hat dir das gesagt?

* Eigentlich ist das nicht genau richtig. Wenn die Zeichenfolge intern ein %code% -Array enthält, wird der Inhalt der Zeichenfolge, solange der Array-Typ ein Referenztyp ist, tatsächlich nicht als Wert übergeben - nur der Verweis auf das Array wäre. Ich denke immer noch, dass dies im Grunde die richtige Antwort ist.

    
___ qstnhdr ___ Warum ist String ein Referenztyp? ___ tag123referenztyp ___ In der Programmiersprachen-Theorie ist ein Referenztyp ein Datentyp, der auf ein Objekt im Speicher verweist. ___
5
Antworten

Wenn Sie einen Typreferenztyp auf null setzen, wirkt sich dies nicht auf den kopierten Typ aus.

Warum ergibt das "0"? %Vor% Nicht b zeigt auf den gleichen Ort und die Einstellung a = null macht effektiv b null?     
09.11.2011, 17:59
6
Antworten

Referenzzyklen mit Wertetypen?

Referenzzyklen in Swift treten auf, wenn Eigenschaften von Referenztypen sich gegenseitig stark beeinflussen (oder mit Schließungen). Besteht jedoch die Möglichkeit, Referenzzyklen mit Werttypen nur zu haben? Ich habe dies in Spielplatz...
04.07.2016, 19:46
3
Antworten

Warum ist String ein Referenztyp?

Warum ist string ein Referenztyp, obwohl er normalerweise primitiver Datentyp wie int, float oder double ist.     
07.09.2010, 05:23
4
Antworten

Haben Interface-Variablen eine Werttyp- oder Referenztyp-Semantik?

Haben Schnittstellenvariablen eine Werttyp- oder Referenztyp-Semantik? Schnittstellen werden nach Typen implementiert, und diese Typen sind entweder Werttypen oder Referenztypen. Offensichtlich implementieren sowohl int als auch string...
16.12.2011, 22:34