Heim Backend-Entwicklung C#.Net-Tutorial Kompilierung von C#-Grundkenntnissen Grundkenntnisse (18) Ein- und Auspacken von Werttypen (1)

Kompilierung von C#-Grundkenntnissen Grundkenntnisse (18) Ein- und Auspacken von Werttypen (1)

Feb 11, 2017 pm 01:49 PM

Es ist tatsächlich sehr interessant, mehr über das Ein- und Auspacken zu erfahren. Schauen wir uns zunächst an, warum es zum Ein- und Auspacken kommt.
Sehen Sie sich den folgenden Code an:

    class Program
    {
        static void Main(string[] args)
        {
            ArrayList array = new ArrayList();

            Point p;//分配一个

            for (int i = 0; i < 5; i++)
            {
                p.x = i;//初始化值

                p.y = i;

                array.Add(p);//装箱
            }
        }
    }

    public struct Point
    {
        public Int32 x;

        public Int32 y;
    }
Nach dem Login kopieren

Führen Sie eine 5-malige Schleife durch, initialisieren Sie jedes Mal ein Feld vom Typ „Punktwert“ und platzieren Sie es dann in der ArrayList. Struct ist eine Struktur vom Typ Wert. Was wird also in ArrayList gespeichert? Schauen wir uns noch einmal die Add-Methode von ArrayList an. Sie können die Add-Methode in MSDN sehen:
public virtual int Add(Object value),
Sie können sehen, dass der Parameter von Add vom Typ Object ist, d. h. der erforderliche Parameter ist ein Verweis auf ein Objekt . Das heißt, die Parameter müssen hier Referenztypen sein. Was ein Referenztyp ist, muss nicht näher erläutert werden. Es handelt sich lediglich um eine Referenz auf ein Objekt auf dem Heap. Zum besseren Verständnis sprechen wir jedoch noch einmal über Heap und Stack.
1. Stapelbereich (Stapel) – wird vom Compiler automatisch zugewiesen und freigegeben und speichert Funktionsparameterwerte, lokale Variablenwerte usw.
2. Heap-Bereich (Heap) – vom Programmierer zugewiesen und freigegeben. Wenn der Programmierer ihn nicht freigibt, kann er vom Betriebssystem recycelt werden, wenn das Programm endet.
Zum Beispiel:

    class Program
    {
        static void Main(string[] args)
        {
            Int32 n;//这是值类型,存放在栈中,Int32初始值为0
            
            A a;//此时在栈中开辟了空间

            a = new A();//真正实例化后的一个对象则保存在堆中。
        }
    }

    public class A
    {
        public A() { }
    }
Nach dem Login kopieren

Zurück zur obigen Frage: Die Add-Methode erfordert Referenztypparameter. Was soll ich tun? Dann müssen Sie Boxen verwenden. Das sogenannte Boxen besteht darin, einen Werttyp in einen Referenztyp umzuwandeln. Der Konvertierungsprozess ist wie folgt:
1. Weisen Sie Speicher im verwalteten Heap zu. Die zugewiesene Speichermenge ist die Speichermenge, die von den einzelnen Feldern des Werttyps benötigt wird, plus die Speichermenge, die von zwei zusätzlichen Mitgliedern (dem Typobjektzeiger und dem synchronisierten Blockindex) benötigt wird, über die alle Objekte im verwalteten Heap verfügen.
2. Kopieren Sie das Werttypfeld in den neu zugewiesenen Speicher.
3. Geben Sie die Adresse des Objekts zurück. Zu diesem Zeitpunkt handelt es sich bei der Adresse um einen Verweis auf ein Objekt, und der Werttyp wurde nun in einen Referenztyp konvertiert.
Auf diese Weise wird in der Add-Methode ein Verweis auf ein eingerahmtes Point-Objekt gespeichert. Das verpackte Objekt bleibt im Heap, bis der Programmierer es verarbeitet oder der Systemmüll es einsammelt. Zu diesem Zeitpunkt überschreitet die Lebensdauer des geschachtelten Werttyps die Lebensdauer des ungeschachtelten Werttyps.
Mit dem obigen Boxen ist es natürlich, es zu entpacken. Wenn Sie das 0. Element des Arrays herausnehmen möchten:
Punkt p = (Punkt)array[0];
Was Sie tun müssen Hier wird abgerufen: Die Referenz des Elements 0 der ArrayList wird in den Punktwerttyp p eingefügt. Um dieses Ziel zu erreichen, muss zunächst die Adresse jedes Point-Felds des Box-Point-Objekts ermittelt werden. Das war’s zum Auspacken. Die in diesen Feldern enthaltenen Werte werden dann vom Heap in die stapelbasierte Werttypinstanz kopiert. Beim Unboxing handelt es sich im Wesentlichen um den Prozess, einen Verweis auf einen primitiven Werttyp zu erhalten, der in einem Objekt enthalten ist. Tatsächlich verweist die Referenz auf den nicht verpackten Teil der verpackten Instanz. Daher ist es beim Unboxing im Gegensatz zum Boxen nicht erforderlich, Bytes in den Speicher zu kopieren. Aber es gibt noch einen weiteren Punkt: Ein Feldkopiervorgang erfolgt unmittelbar nach dem Auspacken.
Daher wirkt sich das Ein- und Auspacken negativ auf die Geschwindigkeit und den Speicherverbrauch des Programms aus. Achten Sie daher darauf, wann das Programm automatisch Ein-/Auspackvorgänge ausführt, und versuchen Sie, diese Situationen beim Schreiben von Code zu vermeiden.
Achten Sie beim Unboxing auf die folgenden Ausnahmen:
1. Wenn die Variable, die „einen Verweis auf die geboxte Werttypinstanz“ enthält, null ist, wird eine NullReferenceException geworfen.
2. Wenn das Objekt, auf das die Referenz zeigt, keine Boxed-Instanz des erwarteten Werttyps ist, wird eine InvalidCastException ausgelöst.
Zum Beispiel das folgende Code-Snippet:

             Int32 x = 5;

            Object o = x;

            Int16 r = (Int16)o;//抛出InvalidCastException异常
Nach dem Login kopieren

Weil es beim Unboxing nur in den ursprünglichen Unboxed-Werttyp konvertiert werden kann. Ändern Sie den obigen Code wie folgt:

             Int32 x = 5;

            Object o = x;

            //Int16 r = (Int16)o;//抛出InvalidCastException异常

            Int16 r = (Int16)(Int32)o;
Nach dem Login kopieren

Das ist richtig.
Nach dem Auspacken erfolgt eine Feldkopie, wie im folgenden Code gezeigt:

            //会发生字段复制
            Point p1;

            p1.x = 1;

            p1.y = 2;

            Object o = p1;//装箱,发生复制

            p1 = (Point)o;//拆箱,并将字段从已装箱的实例复制到栈中
Nach dem Login kopieren

Sehen Sie sich das folgende Codesegment an:

            //要改变已装箱的值

            Point p2;

            p2.x = 10;

            p2.y = 20;

            Object o = p2;//装箱

            p2 = (Point)o;//拆箱

            p2.x = 40;//改变栈中变量的值

            o = p2;//再一次装箱,o引用新的已装箱实例
Nach dem Login kopieren

Der Zweck hier ist das Kopieren die Box Der x-Wert von p2 wird auf 40 geändert. Auf diese Weise müssen Sie das Feld einmal entpacken, das Feld einmal in den Stapel kopieren, den Wert des Felds im Stapel ändern und dann das Boxen durchführen Sie müssen eine neue Instanz auf dem Heap erstellen. Daraus erkennen wir auch die Auswirkungen des Einpackens/Auspackens und Kopierens auf die Programmleistung.
Schauen wir uns noch ein paar Code-Schnipsel zum Boxen und Unboxen an:

            //装箱拆箱演示
            Int32 v = 5;

            Object o = v;

            v = 123;

            Console.WriteLine(v + "," + (Int32)o);
Nach dem Login kopieren

Hier finden drei Mal Boxen statt.

            Object o = v;

            v = 123;
Nach dem Login kopieren

Aber in Boxing trat auch in Console.WriteLine auf. Warum? Da es hier in WriteLine String-Typ-Parameter gibt und jeder weiß, dass String ein Referenztyp ist, muss (Int32)o hier eingerahmt werden. Hier wird erneut das Problem der Verwendung des +-Zeichens zum Verbinden von Zeichenfolgen im Programm erläutert. Wenn während der Verbindung mehrere Werttypen vorhanden sind, werden mehrere Boxing-Operationen ausgeführt.
Der obige Code kann jedoch geändert werden:

            //修改后
            Console.WriteLine(v.ToString() + "," + o);
Nach dem Login kopieren

Auf diese Weise gibt es kein Boxen.
Sehen Sie sich den folgenden Code noch einmal an:

 Int32 v = 5;

            Object o = v;

            v = 123;

            Console.WriteLine(v);

            v = (Int32)o;

            Console.WriteLine(v);
Nach dem Login kopieren

Hier kommt nur eine Box vor, d. h. Object o = v hier, und Console.WriteLine ist mit int, bool, double usw. überladen. es findet also kein Boxen statt.

Das Obige ist der Inhalt der Grundkenntnisse von C# Grundkenntnisse (18) Boxing und Unboxing von Werttypen (1) Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php). cn)!


Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Active Directory mit C# Active Directory mit C# Sep 03, 2024 pm 03:33 PM

Leitfaden zu Active Directory mit C#. Hier besprechen wir die Einführung und die Funktionsweise von Active Directory in C# sowie die Syntax und das Beispiel.

C#-Serialisierung C#-Serialisierung Sep 03, 2024 pm 03:30 PM

Leitfaden zur C#-Serialisierung. Hier besprechen wir die Einführung, die Schritte des C#-Serialisierungsobjekts, die Funktionsweise bzw. das Beispiel.

Zufallszahlengenerator in C# Zufallszahlengenerator in C# Sep 03, 2024 pm 03:34 PM

Leitfaden zum Zufallszahlengenerator in C#. Hier besprechen wir die Funktionsweise des Zufallszahlengenerators, das Konzept von Pseudozufallszahlen und sicheren Zahlen.

C#-Datenrasteransicht C#-Datenrasteransicht Sep 03, 2024 pm 03:32 PM

Leitfaden zur C#-Datenrasteransicht. Hier diskutieren wir die Beispiele, wie eine Datenrasteransicht aus der SQL-Datenbank oder einer Excel-Datei geladen und exportiert werden kann.

Muster in C# Muster in C# Sep 03, 2024 pm 03:33 PM

Leitfaden zu Mustern in C#. Hier besprechen wir die Einführung und die drei wichtigsten Arten von Mustern in C# zusammen mit ihren Beispielen und der Code-Implementierung.

Primzahlen in C# Primzahlen in C# Sep 03, 2024 pm 03:35 PM

Leitfaden zu Primzahlen in C#. Hier besprechen wir die Einführung und Beispiele von Primzahlen in C# sowie die Codeimplementierung.

Fakultät in C# Fakultät in C# Sep 03, 2024 pm 03:34 PM

Leitfaden zur Fakultät in C#. Hier diskutieren wir die Einführung in die Fakultät in C# zusammen mit verschiedenen Beispielen und Code-Implementierungen.

Der Unterschied zwischen Multithreading und asynchronem C# Der Unterschied zwischen Multithreading und asynchronem C# Apr 03, 2025 pm 02:57 PM

Der Unterschied zwischen Multithreading und Asynchron besteht darin, dass Multithreading gleichzeitig mehrere Threads ausführt, während asynchron Operationen ausführt, ohne den aktuellen Thread zu blockieren. Multithreading wird für rechenintensive Aufgaben verwendet, während asynchron für die Benutzerinteraktion verwendet wird. Der Vorteil des Multi-Threading besteht darin, die Rechenleistung zu verbessern, während der Vorteil von Asynchron nicht darin besteht, UI-Threads zu blockieren. Die Auswahl von Multithreading oder Asynchron ist von der Art der Aufgabe abhängt: Berechnungsintensive Aufgaben verwenden Multithreading, Aufgaben, die mit externen Ressourcen interagieren und die UI-Reaktionsfähigkeit asynchron verwenden müssen.

See all articles