Benötigen Sie eine Interpretation des Abschnitts in der C # -Spezifikation

11

Ich lese die C # -Spezifikation . Ich könnte eine Klarstellung für ein Segment gebrauchen:

C # hat ein einheitliches Typsystem. Alle C # -Typen, einschließlich primitiver Typen wie int und double, erben von einem einzelnen Stammobjekttyp. Somit teilen sich alle Typen eine Reihe gemeinsamer Operationen, und Werte jedes Typs können auf konsistente Weise gespeichert, transportiert und bearbeitet werden. Darüber hinaus unterstützt C # sowohl benutzerdefinierte Referenztypen als auch Werttypen und ermöglicht so die dynamische Zuordnung von Objekten sowie die Inline-Speicherung von Lightweight-Strukturen.

Was bedeutet in diesem Zusammenhang „Inline-Speicherung von Leichtbaustrukturen“?

ChuckT
quelle

Antworten:

11

Svicks Antwort ist gut, aber ich dachte, ich würde ein paar zusätzliche Punkte hinzufügen.

Zunächst einmal ist der Absatz fehlerhaft. Zeigertypen erben nicht vom Objekt. Werte, die zur Kompilierungszeit als Schnittstellentypen oder Typparametertypen bekannt sind, sind zur Laufzeit entweder ungültige Referenzen oder echte Instanzen von etwas, das vom Objekt erbt, aber es hat mich immer als seltsam strukturiert zu sagen, dass diese Typen " erben "vom Objekt; Vererbung ist die Eigenschaft, dass Mitglieder des Vorfahren Mitglieder des Nachkommen sind, aber Sie denken normalerweise nicht an "ToString" als Mitglied von IEnumerable. Sie denken, es ist ein Mitglied der Sache, die IEnumerable implementiert .

Der Absatz ist auch fehlerhaft, da dies der einzige Ort ist, an dem "primitiver Typ" in der Spezifikation erscheint und er ohne Definition erscheint. Es ist daher sowohl unnötig als auch verwirrend und sollte entfernt werden.

Ich wollte, dass dieser Absatz für eine Weile behoben wird. Wenn ich Mads das nächste Mal sehe, werde ich ihn daran erinnern.

Um Ihre spezielle Frage zu beantworten: svick ist natürlich richtig, aber es ist hilfreich, ein bestimmtes Beispiel zu sehen. Wenn du sagst:

struct ColorfulInt
{
    int value;
    Color color;
    ...
}

und Sie erstellen beispielsweise ein Array:

ColorfulInt[] x = new ColorFulInt[100];

Dann geht der Speicher für diese 100 Zoll und 100 Farben in das Array selbst . Wenn ColorfulInt stattdessen eine Klasse wäre, würde das Array 100 Verweise auf ColorfulInt enthalten, von denen jeder einzeln zugewiesen werden müsste. Das individuelle Zuweisen dieser hundert Elemente ist zeitlich und räumlich viel weniger effizient als das einfache Zuweisen des Speichers direkt im Array selbst.

Eric Lippert
quelle
Ist die Bedeutung dieser Objekte für die Speicherabstraktion von Bedeutung? Wenn Sie bereit sind, sie zu bearbeiten, sind sie leichter zugänglich, wenn sie sich in einem zusammenhängenden Block adressierbarer Leerzeichen befinden. Verse verweisen darauf, wer weiß wo? Ist das richtig oder fehlt mir noch etwas?
ChuckT
@ChuckT: Richtig. Sie zahlen nicht den Aufwand für die Indirektion, und Sie erhalten auch eine schöne Cache-Lokalität.
Eric Lippert
12

Dies bedeutet, dass Werttypen direkt dort gespeichert werden, wo Sie sie definieren, was sie im Vergleich zu Referenztypen effizienter macht.

Was genau bedeutet das? Wenn Sie eine lokale Variable eines Werttyps haben, wird diese normalerweise direkt auf dem Stapel gespeichert (es gibt jedoch viele Ausnahmen). Wenn Sie ein Feld eines Werttyps haben, wird es direkt in der umschließenden Klasse oder Struktur gespeichert.

svick
quelle
1
Das macht Sinn. Danke, dass du das für mich konkretisiert hast, svick!
ChuckT