C#容易忽视的拆装箱问题
C#容易忽视的拆装箱问题
在值类型的拆装箱中,有些问题容易被忽视
interface IAngle
{
void MoveTo(int degress, int minutes, int seconds);
}
struct Angle : IAngle
{
private int _Degress;
private int _Minutes;
private int _Seconds;
public void MoveTo(int degress, int minutes, int seconds)
{
_Degress = degress;
_Minutes = minutes;
_Seconds = seconds;
}
public override string ToString()
{
return _Degress.ToString();
}
}
class Program
{
static void Main()
{
Angle angle = new Angle();
angle.MoveTo(25, 30, 88);
//#Expamle 1
object objectangle = angle;
Console.WriteLine(((Angle)objectangle).ToString());
//#Expamle 2
((Angle)objectangle).MoveTo(28, 30, 88);
Console.WriteLine(((Angle)objectangle).ToString());
//#Expamle 3
((IAngle)angle).MoveTo(28, 30, 88);
Console.WriteLine(((IAngle)angle).ToString());
//#Expamle 4
((IAngle)objectangle).MoveTo(28, 30, 88);
Console.WriteLine(((Angle)objectangle).ToString());
}
}
// Print:
// 25
// 25
// 25
// 28
在上面的代码中 使用IAngle接口创建了Angle结构,然后在Main函数中使实例化使用了Angle中的方法三次 最后代码输出的结果让人疑惑
在Expamle1中装箱了Angle类型的实例为 object 然后在Console.WriteLine里产生了拆箱操作,此时输出的是obj的副本
Expamle2里使用了拆箱,产生了拷贝,然后调用了拷贝的值里面的方法 原有的objectangle并未被修改,被修改的是拆箱操作时候创建的值拷贝,运行完后已经被抛弃(赋值给_)
Expamle3里产生了装箱操作,也产生了拷贝
Expamle4里强制转换是向引用类型转换,不会产生拷贝,输出了预期的结果
具体查看下图
