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

7

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 IComparable , und int ist ein Werttyp, und string ist ein Referenztyp. Aber was ist damit:

%Vor%

(Die Frage, die ich beantworten wollte, wurde vermutlich gelöscht, weil gefragt wurde, ob Interfaces auf dem Stack oder dem Heap gespeichert sind. Wie wir alle wissen sollten, ist es konstruktiver, Unterschiede zwischen Value- und Reference-Typen zu berücksichtigen Begriffe für ihre Semantik und nicht für ihre Umsetzung. Für eine Diskussion, siehe Eric Lipperts Der Stack ist ein Implementierungsdetail .)

    
phoog 16.12.2011, 22:34
quelle

4 Antworten

11

Normalerweise ist es gemäß den vorhandenen Antworten ein Referenztyp und erfordert Boxen; Es gibt jedoch eine Ausnahme (nicht immer?). In einer generischen Methode mit einer where -Einschränkung kann beide sein:

%Vor%

Dies ist eine eingeschränkte -Operation, die nicht in eingerahmt ist, auch wenn ein Werttyp ist. Dies wird über constrained erreicht. Stattdessen führt der JIT die Operation als virtueller Aufruf für Referenztypen und als statischen Aufruf für Werttypen aus. Kein Boxen.

    
Marc Gravell 16.12.2011, 23:05
quelle
5

Hier geht es darum zu verstehen, Boxen und Unboxing von Typen. In Ihrem Beispiel wird der Int bei der Zuweisung eingerahmt, und ein Verweis auf dieses "Feld" oder Objekt ist das, was x zugewiesen ist. Der Werttyp int ist als eine Struktur definiert, die IComparable implementiert. Sobald Sie jedoch diese Schnittstellenreferenz verwenden, um auf den Werttyp int zu verweisen, wird sie in einem Rahmen platziert und auf dem Heap platziert. So funktioniert es in der Praxis. Die Tatsache, dass die Verwendung einer Schnittstellenreferenz das definitive Boxen per Definition zur Folge hat, macht diese Referenztyp-Semantik.

MSDN: Boxen und Unboxing

    
Eben Geer 16.12.2011 22:51
quelle
3

Eine Variable oder ein Feld vom Typ IComparable ist unabhängig vom Typ des diesem Feld zugewiesenen Werts eine Variable oder ein Feld vom Referenztyp. Dies bedeutet, dass x im Beispielcode eingerahmt ist.

Ein einfacher Test wird das demonstrieren. Der Test basiert auf der Tatsache, dass Sie nur einen Werttyp auf seinen ursprünglichen Typ (und die Nullable-Version dieses Typs) aufheben können :

%Vor%

BEARBEITEN

Darüber hinaus definiert die C # -Spezifikation reference-type ausdrücklich als Klassen-, Schnittstellentypen, Array-Typen und Delegattypen.

BEARBEITEN 2

Wie Marc Gravell in seiner Antwort betont, ist ein generischer Typ mit einer Schnittstellenbeschränkung ein anderer Fall. Dies bewirkt nicht Boxen.

    
phoog 16.12.2011 22:34
quelle
2

Variablen des Interface-Typs haben immer entweder unveränderliche Semantik, veränderbare Referenzsemantik oder "Oddball" -Semantik (etwas anderes als normale Referenz- oder Wertesemantik). Wenn variable1 und variable2 beide als derselbe Schnittstellentyp deklariert sind, führt einer variable2 = variable1 aus, und einer schreibt nie wieder in eine Variable, die Instanz, auf die sich variable1 bezieht, wird immer nicht von der einen unterschieden variable2 (da es dieselbe Instanz ist).

Generische Typen mit Schnittstellenbeschränkungen können eine unveränderliche Semantik, eine veränderbare Referenzsemantik oder eine "skurrile" Semantik aufweisen, können jedoch auch eine Semantik veränderbarer Werte aufweisen. Dies kann gefährlich sein, wenn die Schnittstelle nicht als änderbare Wertesemantik dokumentiert ist. Leider gibt es keine Möglichkeit, eine Schnittstelle so zu beschränken, dass sie entweder eine unveränderliche Semantik oder eine Semantik mit änderbarem Wert hat (dh nach variable2 = variable1 sollte es nicht möglich sein, variable1 zu ändern, indem variable2 geschrieben wird, und umgekehrt). Man könnte eine "struct" -Beschränkung zusammen mit der Schnittstellenbeschränkung hinzufügen, aber das würde Klassen ausschließen, die eine unveränderliche Semantik haben, während Strukturen mit Bezugssemantik nicht ausgeschlossen sind.

    
supercat 16.12.2011 23:22
quelle