recherche
Maisondéveloppement back-endTutoriel C#.NetCompilation de connaissances sur la boxe et le déballage C#

1. La boxe et le déballage sont des concepts abstraits
2. La boxe convertit les types de valeur en types de référence

Le déballage convertit les types de référence en types de valeur

À l'aide des fonctions de boxe et de déballage, les types valeur peuvent être liés aux types référence en permettant à n'importe quelle valeur du type valeur d'être convertie vers et depuis le type Objet

Par exemple :

int val = 100; 
object obj = val; 
Console.WriteLine (“对象的值 = {0}", obj);

Il s'agit d'un processus de boxe, qui est le processus de conversion des types valeur en types référence

int val = 100; 
object obj = val; 
int num = (int) obj; 
Console.WriteLine ("num: {0}", num);

Il s'agit d'un processus de déballage, qui est le processus de conversion des types valeur en types référence, puis par types référence Le processus de conversion en une valeur type

Remarque : seuls les objets encadrés peuvent être déballés
3. Dans .NET, les types de données sont divisés en types de valeur et en types de référence (non équivalents aux pointeurs), L'allocation de mémoire est donc divisée en deux De différentes manières, l'un est la pile et l'autre est le tas (remarque : il s'agit d'un tas géré)
Les types de valeur ne seront alloués que sur la pile.
Les types de référence allouent de la mémoire et du tas géré.
Le tas géré correspond au garbage collection.

4 : Qu’est-ce que le boxing/unboxing ?
Boxing : utilisé pour stocker les types de valeur dans le tas de garbage collection. La boxe est une conversion implicite d’un type valeur en type objet ou en tout type d’interface implémenté par le type valeur.
Unboxing : une conversion explicite d'un type d'objet en un type valeur ou d'un type d'interface en un type valeur qui implémente l'interface.

5 : Pourquoi un emballage est-il nécessaire ? (Pourquoi convertir les types valeur en types référence ?)
L'un des scénarios les plus courants consiste à appeler une méthode avec un paramètre de type Object. L'Object peut prendre en charge n'importe quel type pour une utilisation universelle. Lorsque vous devez transmettre un type valeur (tel que Int32), la boxe est requise.
Une autre utilisation est un conteneur non générique, également pour garantir l'universalité, le type d'élément est défini comme Objet. Par conséquent, lors de l’ajout de données de type valeur à un conteneur, le boxing est requis.

6 : Opérations internes de boxing/unboxing

Boxing
Alloue une instance d'objet dans le tas pour un type de valeur et copie la valeur dans un nouvel objet. Suivez trois étapes.

Mémoire de tas gérée nouvellement allouée (la taille est la taille de l'instance de type valeur plus un pointeur de table de méthodes et un SyncBlockIndex).
Copiez les champs d'instance du type valeur dans la mémoire nouvellement allouée.
Renvoie l'adresse de l'objet nouvellement alloué dans le tas géré. Cette adresse est une référence à l'objet.
Certaines personnes le comprennent ainsi : si Int32 est encadré, l'adresse renvoyée pointe vers un Int32. Je pense qu'il n'est pas impossible de le comprendre de cette façon, mais cela pose des problèmes. Premièrement, il n'est pas complet et, deuxièmement, pointer vers Int32 ne révèle pas son essence (dans le tas géré).

Unboxing
Vérifie l'instance d'objet pour s'assurer qu'il s'agit d'une valeur encadrée du type de valeur donné. Copie la valeur de l'instance dans une variable de type valeur.
Selon certains livres, le déballage n'obtient que le pointeur vers la partie type valeur de l'objet de référence, et la copie du contenu est le déclencheur de l'instruction d'affectation. Je ne pense pas que cela ait de l'importance. La chose la plus importante est de vérifier la nature de l'instance d'objet. Les types de unboxing et de boxing doivent correspondre. À ce stade, au niveau de la couche IL, je ne vois pas le principe, c'est peut-être qu'une méthode comme GetType est appelée. . Supprimez le type pour la correspondance (car une correspondance stricte est requise).

7 : L'impact du boxing/unboxing sur l'efficacité d'exécution

Évidemment, cela ressort du principe que lors du boxing, un tout nouvel objet de référence est généré, ce qui prendra du temps, c'est-à-dire, ce qui entraîne une efficacité réduite.
Que faire ?
Tout d’abord, la boxe doit être évitée autant que possible.
Par exemple, les deux situations de l'exemple 2 ci-dessus peuvent être évitées. Dans le premier cas, cela peut être évité en surchargeant la fonction. Le deuxième cas peut être évité grâce aux génériques.
Bien sûr, rien n'est absolu. Supposons que le code que vous souhaitez modifier soit un assembly tiers et que vous ne puissiez pas le modifier, vous ne pouvez alors que le mettre en boîte.
Pour l'optimisation du code de boxing/unboxing, puisque le boxing et le unboxing sont implicites en C#, la méthode fondamentale est d'analyser le code, et la manière la plus directe d'analyser est de comprendre la structure principale Voir le code IL décompilé.

Par exemple : il peut y avoir une boxe redondante dans le corps de la boucle, vous pouvez simplement utiliser une boxe avancée pour l'optimisation.

8 : Meilleure compréhension de l'emballage/unboxing

L'emballage/unboxing n'est pas aussi simple et clair que mentionné ci-dessus

Par exemple : lors de l'emballage, changez Pour référencer un objet, il y aura un pointeur de table de méthode supplémentaire. A quoi sert-il ?

Nous pouvons explorer davantage avec des exemples.

Par exemple :

Struct A : ICloneable
{
public Int32 x;
public override String ToString() {
return String.Format(”{0}”,x);
}
public object Clone() {
return MemberwiseClone();
}
}
static void main() 
{ 
A a; 
a.x = 100; 
Console.WriteLine(a.ToString()); 
Console.WriteLine(a.GetType()); 
A a2 = (A)a.Clone(); 
ICloneable c = a2; 
Ojbect o = c.Clone(); 
}

a.ToString()。编译器发现A重写了ToString方法,会直接调用ToString的指令。因为A是值类型,编译器不会出现多态行为。因此,直接调用,不装箱。(注:ToString是A的基类System.ValueType的方法) 
a.GetType(),GetType是继承于System.ValueType的方法,要调用它,需要一个方法表指针,于是a将被装箱,从而生成方法表指针,调用基类的System.ValueType。(补一句,所有的值类型都是继承于System.ValueType的)。 
a.Clone(),因为A实现了Clone方法,所以无需装箱。 
ICloneable转型:当a2为转为接口类型时,必须装箱,因为接口是一种引用类型。 
c.Clone()。无需装箱,在托管堆中对上一步已装箱的对象进行调用。 
附:其实上面的基于一个根本的原理,因为未装箱的值类型没有方法表指针,所以,不能通过值类型来调用其上继承的虚方法。另外,接口类型是一个引用类型。对此,我的理解,该方法表指针类似C++的虚函数表指针,它是用来实现引用对象的多态机制的重要依据。

9:如何更改已装箱的对象

对于已装箱的对象,因为无法直接调用其指定方法,所以必须先拆箱,再调用方法,但再次拆箱,会生成新的栈实例,而无法修改装箱对象。有点晕吧,感觉在说绕口令。还是举个例子来说:(在上例中追加change方法) 

public void Change(Int32 x) { 
this.x = x; 
}

调用: 

A a = new A(); 
a.x = 100; 
Object o = a; //装箱成o,下面,想改变o的值
((A)o).Change(200); //改掉了吗?没改掉
没改掉的原因是o在拆箱时,生成的是临时的栈实例A,所以,改动是基于临时A的,并未改到装箱对象。

(附:在托管C++中,允许直接取加拆箱时第一步得到的实例引用,而直接更改,但C#不行。) 
那该如何是好? 
嗯,通过接口方式,可以达到相同的效果。 
实现如下: 

interface IChange { 
void Change(Int32 x); 
} 
struct A : IChange { 
… 
}

调用: 

((IChange)o).Change(200);//改掉了吗?改掉了

为啥现在可以改?


在将o转型为IChange时,这里不会进行再次装箱,当然更不会拆箱,因为o已经是引用类型,再因为它是IChange类型,所以可以直接调用Change,于是,更改的也就是已装箱对象中的字段了,达到期望的效果。

10、将值类型转换为引用类型,需要进行装箱操作(boxing):

首先从托管堆中为新生成的引用对象分配内存
然后将值类型的数据拷贝到刚刚分配的内存中
返回托管堆中新分配对象的地址
可以看出,进行一次装箱要进行分配内存和拷贝数据这两项比较影响性能的操作。

将引用类型转换为值类型,需要进行拆箱操作(unboxing):

首先获取托管堆中属于值类型那部分字段的地址,这一步是严格意义上的拆箱。
将引用对象中的值拷贝到位于线程堆栈上的值类型实例中。
经过这2步,可以认为是同boxing是互反操作。严格意义上的拆箱,并不影响性能,但伴随这之后的拷贝数据的操作就会同boxing操作中一样影响性能。

11、

NET的所有类型都是由基类System.Object继承过来的,包括最常用的基础类型:int, byte, short,bool等等,就是说所有的事物都是对象。

如果申明这些类型得时候都在堆(HEAP)中分配内存,会造成极低的效率!(个中原因以及关于堆和栈得区别会在另一篇里单独得说说!)
.NET如何解决这个问题得了?正是通过将类型分成值型(value)和引用型(regerencetype),

C#中定义的值类型和引用类型

值类型:原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举(enum)、结构(struct)
引用类型:类、数组、接口、委托、字符串等
值型就是在栈中分配内存,在申明的同时就初始化,以确保数据不为NULL;
引用型是在堆中分配内存,初始化为null,引用型是需要GARBAGE COLLECTION来回收内存的,值型不用,超出了作用范围,系统就会自动释放!
下面就来说装箱和拆箱的定义!
装箱就是隐式的将一个值型转换为引用型对象。比如:

int i=0;
Syste.Object obj=i;

这个过程就是装箱!就是将i装箱!
拆箱就是将一个引用型对象转换成任意值型!比如:

int i=0;
System.Object obj=i;
int j=(int)obj;

这个过程前2句是将i装箱,后一句是将obj拆箱!

更多c#装箱和拆箱知识整理相关文章请关注PHP中文网!


Déclaration
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
C # et .NET: Comprendre la relation entre les deuxC # et .NET: Comprendre la relation entre les deuxApr 17, 2025 am 12:07 AM

La relation entre C # et .NET est inséparable, mais ce ne sont pas la même chose. C # est un langage de programmation, tandis que .NET est une plate-forme de développement. C # est utilisé pour écrire du code, compiler dans le langage intermédiaire de .NET (IL) et exécuté par .NET Runtime (CLR).

La pertinence continue de C # .net: un regard sur l'utilisation actuelleLa pertinence continue de C # .net: un regard sur l'utilisation actuelleApr 16, 2025 am 12:07 AM

C # .NET est toujours important car il fournit des outils et des bibliothèques puissants qui prennent en charge le développement d'applications multiples. 1) C # combine .NET Framework pour rendre le développement efficace et pratique. 2) Le mécanisme de collecte de la sécurité et des ordures de C # améliore ses avantages. 3) .NET fournit un environnement de course multiplateforme et des API riches, améliorant la flexibilité du développement.

Du Web au bureau: la polyvalence de C # .netDu Web au bureau: la polyvalence de C # .netApr 15, 2025 am 12:07 AM

C # .NETtisversatileforbothwebandDeskTopDevelopment.1) forweb, useasp.netfordynamicapplications.2) fordesktop, employwindowsformSorwpfforrichInterfaces.3) usexamarinforcross-plateformDevelopment, permanant les codéescosswindows, macos, linux, etmobiledevices.

C # .NET et l'avenir: s'adapter aux nouvelles technologiesC # .NET et l'avenir: s'adapter aux nouvelles technologiesApr 14, 2025 am 12:06 AM

C # et .NET s'adaptent aux besoins des technologies émergentes à travers des mises à jour et des optimisations continues. 1) C # 9.0 et .NET5 introduire le type d'enregistrement et l'optimisation des performances. 2) .netcore améliore le support natif et conteneurisé cloud. 3) ASP.Netcore s'intègre aux technologies Web modernes. 4) ML.NET prend en charge l'apprentissage automatique et l'intelligence artificielle. 5) La programmation asynchrone et les meilleures pratiques améliorent les performances.

C # .NET vous convient-il? Évaluer son applicabilitéC # .NET vous convient-il? Évaluer son applicabilitéApr 13, 2025 am 12:03 AM

C # .NeTissuitableFormenterprise-LevelApplications withithemicrosofosystématetoitsstrongThpyping, RichLibrary, androbustperformance.wowever, itmayNotBeidealForcross-PlatformDevelopmentorwhenRawpeediscritical, whileLanguageSlikerUstorGomightBeferable.

C # code dans .NET: Explorer le processus de programmationC # code dans .NET: Explorer le processus de programmationApr 12, 2025 am 12:02 AM

Le processus de programmation de C # dans .NET comprend les étapes suivantes: 1) l'écriture de code C #, 2) la compilation dans un langage intermédiaire (IL) et 3) l'exécution par .NET Runtime (CLR). Les avantages de C # dans .NET sont sa syntaxe moderne, son système de type puissant et son intégration serrée avec le Framework .NET, adapté à divers scénarios de développement des applications de bureau aux services Web.

C # .NET: Explorer les concepts de base et les principes fondamentaux de la programmationC # .NET: Explorer les concepts de base et les principes fondamentaux de la programmationApr 10, 2025 am 09:32 AM

C # est un langage de programmation moderne et orienté objet développé par Microsoft et dans le cadre du .NET Framework. 1.C # prend en charge la programmation orientée objet (POO), y compris l'encapsulation, l'héritage et le polymorphisme. 2. La programmation asynchrone en C # est implémentée via Async et attend des mots clés pour améliorer la réactivité des applications. 3. Utilisez LINQ pour traiter les collections de données concisement. 4. Les erreurs courantes incluent les exceptions de référence NULL et les exceptions indexes hors gamme. Les compétences de débogage comprennent l'utilisation d'un débogueur et une gestion des exceptions. 5. L'optimisation des performances comprend l'utilisation de StringBuilder et d'éviter l'emballage et le déballage inutiles.

Test C # .NET Applications: unité, intégration et tests de bout en boutTest C # .NET Applications: unité, intégration et tests de bout en boutApr 09, 2025 am 12:04 AM

Les stratégies de test pour les applications C # .NET comprennent les tests unitaires, les tests d'intégration et les tests de bout en bout. 1. Le test unitaire garantit que l'unité minimale du code fonctionne indépendamment, en utilisant le cadre MSTEST, NUnit ou Xunit. 2. Les tests intégrés vérifient les fonctions de plusieurs unités combinées et des données simulées couramment utilisées et des services externes. 3. Les tests de bout en bout simulent le processus de fonctionnement complet de l'utilisateur et le sélénium est généralement utilisé pour les tests automatisés.

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Version crackée d'EditPlus en chinois

Version crackée d'EditPlus en chinois

Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code

Version Mac de WebStorm

Version Mac de WebStorm

Outils de développement JavaScript utiles

Navigateur d'examen sécurisé

Navigateur d'examen sécurisé

Safe Exam Browser est un environnement de navigation sécurisé permettant de passer des examens en ligne en toute sécurité. Ce logiciel transforme n'importe quel ordinateur en poste de travail sécurisé. Il contrôle l'accès à n'importe quel utilitaire et empêche les étudiants d'utiliser des ressources non autorisées.

SublimeText3 version anglaise

SublimeText3 version anglaise

Recommandé : version Win, prend en charge les invites de code !

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP