首页 新闻 会员 周边 捐助

这个地方为什么值类型被封装了?请教大家

1
悬赏园豆:10 [已解决问题] 解决于 2012-07-10 18:43

 《CLR via C#(第三版)》中第124页。   

using System;

internal struct Point{

private Int32 m_x,m_y;

 

public Point(Int32 x,Int32 y){ m_x=x;m_y=y; }

 

public void ChangePoint(Int32 x,Int32 y)

{ m_x=x;m_y=y; }

 

public override String ToString()

{ return String.Format("({0},{1})“,m_x,m_y); }

 

}

public sealed class Program

{

public static void Main(){

Point p=new Point(1,1);

Console.WriteLine(p);

 

p.Change(2,2);

Console.WriteLine(p);

 

Object o=p;

Console.WriteLine(o);

 

((Point)o).Change(3,3);

Console.WriteLine(o);

}

}

A、作者说在第一次调用WriteLine之前,p要进行封装,WriteLine会在已装箱的Point上调用ToString,并与其的那样显示(1,1)。【我就没弄懂为什么是在在WriteLine之前就封装了,不是在WriteLine的时候封装吗???】   

  我理解的是在WriteLine方法的时候进行了封装。 但是他的意思是在之前就封装了再WriteLine里面调用了ToString方法,这儿没有搞懂。。。

B、然后p调用Change方法,把m_xhe m_y都修改为2,第二次调用WriteLine时,要求再次对p进行封装,并预期的那样显示(2,2) 这个我可以理解的。

Max蚊子的主页 Max蚊子 | 菜鸟二级 | 园豆:209
提问于:2012-07-09 22:49
< >
分享
最佳答案
0

因为此时WriteLine使用的是 object 参数,那么在调用 WriteLine 之前,需要先把Point转换为Object类型。WriteLine只负责接收Object类型的参数,这个Object类型的参数是怎么得来的是不由WriteLine来管的。

收获园豆:3
Launcher | 高人七级 |园豆:45050 | 2012-07-10 10:04
其他回答(2)
0

“WriteLine会在已装箱的Point上调用ToString”

这句话没问题,装好箱,WriteLine才能调用ToString。

这名话并没有说在WriteLine语句执行之前进行装箱。

这里有一篇不错的图文并茂的装箱方面的文章:

The C# Value Type and Boxing

收获园豆:4
dudu | 园豆:30757 (高人七级) | 2012-07-10 09:17
0

确实是调用WriteLine之前进行的装箱,因为p是Point值类型,那么对应的WriteLine重载是:

public static void WriteLine(object value);

因此p被装箱,然后再作为参数传到WriteLine方法。如果你看生成的IL,就很清楚了,大概是这样子:

    L_0003: initobj ConsoleApp.Program/Point
    L_0009: ldloc.0 
    L_000a: box ConsoleApp.Program/Point
    L_000f: call void [mscorlib]System.Console::WriteLine(object)

可以看出是先box操作,再call方法,并不是方法体具有装箱的职能。

收获园豆:3
水牛刀刀 | 园豆:6350 (大侠五级) | 2012-07-10 10:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册