Maison >développement back-end >Tutoriel C#.Net >Compilation des connaissances de base en C# Connaissances de base (19) Boxing et unboxing des types valeur (2)
Si le code provoque une boxe répétée par le compilateur, vous pouvez le modifier en boxe manuelle pour que le code s'exécute plus rapidement :
//手动装箱 Int32 v = 5; //由于string.Format的参数是object类型,所以这里会造成三次装箱。 Console.WriteLine(string.Format("{0},{1},{2}", v, v, v)); //修改一下,当然这只是一个小技巧,比如程序中对同一个值的同一个操作执行多次, //应该都是要先执行一次,然后再使用的。 Object o = v;//装箱一次 Console.WriteLine(string.Format("{0},{1},{2}", o, o, o));
Grâce au segment de code précédent, nous Quand. en écrivant un programme, il est facile de déterminer quand un type valeur doit être encadré. Ce n'est rien de plus que de la boxe lorsque vous souhaitez obtenir une référence à un type valeur. La différence entre les types valeur et les types référence peut également être clairement visible ici :
1. Les types valeur n'attribuent pas d'espace dans le tas géré ; tandis que les types référence allouent les membres spécifiés dans la classe sur le tas après l'instanciation.
2. Les types valeur n'ont pas de membres d'objets supplémentaires sur le tas, à savoir "pointeur d'objet de type" et "index de synchronisation".
Les types de valeur non boxés n'ont pas d'index synchronisés, vous ne pouvez donc pas utiliser les méthodes (telles que le verrouillage) de la classe dans laquelle se trouve le type pour permettre à plusieurs threads de synchroniser l'accès à cette instance.
Bien que les types valeur non boxés n'aient pas de pointeurs d'objet de type, les méthodes virtuelles héritées ou remplacées par le type peuvent toujours être appelées, telles que Equals, GetHashCode et ToString. Si un type valeur remplace l’une de ces méthodes virtuelles, le CLR peut appeler cette méthode de manière non virtuelle car le type valeur est implicitement scellé et aucun type ne peut en être dérivé. De plus, les instances de type valeur utilisées pour appeler des méthodes virtuelles ne sont pas encadrées. Si la méthode virtuelle substituée appelle l’implémentation de la méthode dans la classe de base, l’instance de type valeur sera encadrée lorsque l’implémentation de la classe de base est appelée. Étant donné que ces méthodes sont définies par System.Object, elles s'attendent à ce que cet argument soit un pointeur vers un objet sur le tas.
De plus, la conversion d'une instance non boxée d'un type valeur vers l'une des interfaces du type nécessite que l'instance soit boxée. Parce que la variable d'interface doit contenir une référence à un objet sur le tas. Regardez le code suivant :
class Program { static void Main(string[] args) { Point p1 = new Point(10, 10); Point p2 = new Point(20, 20); //调用ToString不装箱,这里ToString是一个虚方法 Console.WriteLine(p1.ToString()); //GetType是一个非虚方法,p1要装箱 Console.WriteLine(p1.GetType()); //这里调用的是public int CompareTo(Point p) //p2不会装箱 Console.WriteLine(p1.CompareTo(p2)); //p1要装箱,这就是将未装箱的值类型转为类型的某个接口时 IComparable c = p1; Console.WriteLine(c.GetType()); //这里调用的是public Int32 CompareTo(Object o), //而且c本来就是一个引用,因此不装箱了 Console.WriteLine(p1.CompareTo(c)); //这里调用的是c的CompareTo方法,参数是object型的 //所以要对p2装箱 Console.WriteLine(c.CompareTo(p2)); //对c拆箱,并复制值到p2中 p2 = (Point)c; Console.WriteLine(p2.ToString()); } } internal struct Point : IComparable { private Int32 x; private Int32 y; public Point(Int32 x, Int32 y) { this.x = x; this.y = y; } public override string ToString() { return string.Format("{0},{1}", x, y);//这里装箱两次,不知道有没好办法。 } public int CompareTo(Point p) { return Math.Sign(Math.Sqrt(x * x + y * y) - Math.Sqrt(p.x * p.x + p.y * p.y)); } public Int32 CompareTo(Object o) { if (GetType() != o.GetType()) { throw new ArgumentException("o is not Point."); } return CompareTo((Point)o); } }
Ce qui précède est la connaissance de base de C# (19) Boxing et unboxing des types de valeur (2 Pour plus de contenu connexe, veuillez faire attention au PHP). Site chinois (www.php.cn) !