值类型装箱

在参数为Object的方法中,使用值类型作为参数,需要经过装箱。装箱需在托管堆分配内存,将值类型的字段复制到新分配的内存,返回对象的地址,会造成性能损失

已装箱的值类型在修改字段时需要,先拆箱,复制字段,修改字段,重新装箱,同样会造成性能损失。在Cli等语言中,可以直接修改装箱后值类型的字段,但是C#中不可以。

未装箱的值类型不能使用System.Threading.Monitor类的方法。

值类型在调用System.Object类实现的方法时,需要进行装箱。
例如ToString(),GetType()

值类型在转型为接口时需要装箱。

在c#中对已装箱的值类型的字段进行修改时,不会修改原值类型的字段。通过接口方法可以修改(将已装箱的对象转型成接口调用),但是,值类型的成员不应该修改值类型的字段。

using System;

internal interface IChangeBoxedPoint
{
void Change(int x, int y);
}

internal struct Point : IChangeBoxedPoint
{
private int m_x, m_y;
public Point(int x, int y)
{
m_x = x;
m_y = y;
}
public void Change(int x, int y)
{
m_x = x;
m_y = y;
}
public override string ToString()
{
return $”({m_x},{m_y})”;
}
}
public class Program
{
public static void Main()
{
Point p = new Point(1, 1);
Console.WriteLine(p);//(1,1)

p.Change(2, 2);
Console.WriteLine(p);//(2,2)

Object o = p;
Console.WriteLine(o);//(2,2)

((Point)o).Change(3, 3);
Console.WriteLine(o);//(2,2)

((IChangeBoxedPoint)p).Change(4, 4);
Console.WriteLine(p);//(2,2)

((IChangeBoxedPoint)o).Change(5, 5);
Console.WriteLine(o);//(5,5)
Console.ReadLine();

}
}

 

Posted in C#

发表回复

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据