在参数为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();
}
}