本帖最后由 skyaspnet 于 2009-09-17 01:20:07 编辑

解决方案 »

  1.   

    i.ToString()。编译器发现 i 重写了ToString方法,会直接调用ToString的指令。
    i 是值类型,编译器不会出现多态行为。
    因此,直接调用,不装箱。
    ToString是 i 的基类System.ValueType的方法 
      

  2.   

    看看测试用例的MSIL文本,没有装箱(box)过程        static void Main(string[] args)
            {
                int i = 100;
                System.Console.Write(i.ToString());
            }        // 下面是 MSIL 文本,仅保留了Main()
            //  .class private auto ansi beforefieldinit test1.Program
            //  extends [mscorlib]System.Object
            //  {
            //  .method private hidebysig static void  Main(string[] args) cil managed
            //  {
            //    .entrypoint
            //    .maxstack  1
            //    .locals init (int32 V_0)
            //    IL_0000:  nop
            //    IL_0001:  ldc.i4.s 100
            //    IL_0003:  stloc.0
            //    IL_0004:  ldloca.s V_0
            //    IL_0006:  call instance string [mscorlib]System.Int32::ToString()
            //    IL_000b:  call void [mscorlib]System.Console::Write(string)
            //    IL_0010:  nop
            //    IL_0011:  ret
            //  } // end of method Program::Main
      

  3.   

    查了一下CLR via Cs,说的也有点模糊,总之就是有两个原因,1是值类型没有type object, 另一个是因为值类型没有办法被继承,因此虽然ToString是Virtual的,但是可以确定是调用本类的实现 而不是调用继承类的实现(因为不可能有继承类).
    代码实例节选:
    Point p1 = new Point(10, 10);
    Console.WriteLine(p1.ToString());解释:
    Calling ToString In the call to ToString, p1 doesn't have to be boxed. At first, you'd
    think that p1 would have to be boxed because ToString is a virtual method that is inherited
    from the base type, System.ValueType. Normally, to call a virtual method, the CLR
    needs to determine the object's type in order to locate the type's method table. Since p1
    is an unboxed value type, there's no type object pointer. However, the C# compiler sees
    that Point overrides the ToString method, and it emits code that calls ToString directly
    (nonvirtually) without having to do any boxing. The compiler knows that polymorphism
    can't come into play here since Point is a value type, and no type can derive from
    it to provide another implementation of this virtual method.
      

  4.   

    int i = 100;
    Console.Write(i.ToString()); // 仅仅是对 i 调用 Int32 的实例方法 ToString(),
                                     // 不是把值类型转换为引用类型,不涉及装箱的问题。object o = (object)i; // 这样,就有装箱操作了
    int j = (int)o;       // 此时,拆箱。
      

  5.   

    装箱在形式上只有4种
    (object)a
    (ValueType)a
    (Enum)a
    (SomeInterface)a
    因为值类型不支持继承,所以其“基类”只可能是这4种
      

  6.   

    值类型自己的ToString()方法,因为其类型是值类型,所以不装箱
    举个例子。 
    Struct A : ICloneable 

    public Int32 x; 
    public override String ToString() { 
    return String.Format(”{0}”,x); 

    public object Clone() { 
    return MemberwiseClone(); 


    static void main() 

    A a; 
    a.x = 100; 
    Console.WriteLine(a.ToString()); 
    Console.WriteLine(a.GetType()); 
    A a2 = (A)a.Clone(); 
    ICloneable c = a2; 
    Ojbect o = c.Clone(); 

    0:a.ToString()。编译器发现A重写了ToString方法,会直接调用ToString的指令。因为A是值类型,编译器不会出现多态行为。因此,直接调用,不装箱。(注:ToString是A的基类System.ValueType的方法) 
    1:a.GetType(),GetType是继承于System.ValueType的方法,要调用它,需要一个方法表指针,于是a将被装箱,从而生成方法表指针,调用基类的System.ValueType。(补一句,所有的值类型都是继承于System.ValueType的)。 
    2:a.Clone(),因为A实现了Clone方法,所以无需装箱。 
    3:ICloneable转型:当a2为转为接口类型时,必须装箱,因为接口是一种引用类型。 
    4:c.Clone()。无需装箱,在托管堆中对上一步已装箱的对象进行调用。 
    附:其实上面的基于一个根本的原理,因为未装箱的值类型没有方法表指针,所以,不能通过值类型来调用其上继承的虚方法。另外,接口类型是一个引用类型。对此,我的理解,该方法表指针类似C++的虚函数表指针,它是用来实现引用对象的多态机制的重要依据。 
      

  7.   

    http://javasky.bloghome.cn/posts/183310.html
    看看这个.看第8条
      

  8.   

    int32里面的tostring()[SecuritySafeCritical]
    public override string ToString()
    {
        return Number.FormatInt32(this, null, NumberFormatInfo.CurrentInfo);

    [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
    public static extern string FormatInt32(int value, string format, NumberFormatInfo info);
       
    貌似看不出什么哦
      

  9.   

    可能是值类型的ToString()方法,不是很清楚.String是个很奇怪的引用类型.
      

  10.   

    FormatInt32还是自动同步的方法
      

  11.   

    空军说的对,调用ToString()方法跟拆装箱扯不着关系
      

  12.   

        装箱与拆箱操作只会在将一个对象由值类型转换为引用类型或引用到值的转换时发生,int.ToString()仅仅是int的一个方法,将int作为一个字符串表现出来,根本不存在类型的转换,何来装箱与拆箱操作??
        int i = 1; i.ToString()之后产生了一个新的对象"1", 跟原来的i没有任何关系,稍微有点计算机知识的人都知道,1和"1"完全是两回事。象object o = i 和 i = (int)o的操作,操作的对象始终是1,只不过这个1被保存在栈(i)或者堆(o)上,这个时候才会产生装箱和拆箱的操作。
      

  13.   

    上面的意思就是说 值类型自己实现了toString()方法,所以不会装箱如果没实现,那就要调用object的tostring()方法,那才会装箱
      

  14.   

    把int,double等看做“值类型”,只不过是我们(包括.net framework)一厢情愿罢了!