最近看了下类型转换我想知道Int32,Single等基元类型是如何实现强制类型转换的。他们内部到底有没有实现IConvertible 接口?看Decimal类,他比较特殊,其中有转换操作符的方法
所以在使用(Int)Decimal的时候会自动找到定义的方法;也可以使用内部的ToXXX()方法,还可以通过Convert来实现public static void Main()
    {
        decimal d;
        int f =decimal.ToInt32(d);
        int g = Convert.ToInt32(d);
        int h = (int)d;
    }
    
 IL_0015:  ldloc.1
  IL_0016:  call       int32 [mscorlib]System.Decimal::ToInt32(valuetype [mscorlib]System.Decimal)
  IL_001b:  stloc.3
  IL_001c:  ldloc.1
  IL_001d:  call       int32 [mscorlib]System.Convert::ToInt32(valuetype [mscorlib]System.Decimal)
  IL_0022:  stloc.s    V_4
  IL_0024:  ldloc.1
  IL_0025:  call       int32 [mscorlib]System.Decimal::op_Explicit(valuetype [mscorlib]System.Decimal)
  IL_002a:  stloc.s    V_5对于其他基元类型比如Int32,使用强制类型时会产生一个conv.i4的指令,我想知道,他内部有没有op_Explicit(valuetype [mscorlib]System.Int32)这样的转换操作符方法。还有就是,他内部是否实现了ToXXX()方法?还是实现了只是没有开放?既然继承了IConvertible 接口,为什么不和Decimal一样提供T0XXX()方法?

解决方案 »

  1.   

    用Reflector看看System.Int32怎么写的就知道
      

  2.   

    我看了下!1:Int32里是类似下面的方法,可以发现实际是调用了Convert.ToInt16里的实现
    并且是收保护的方法。内部也没有转换操作符。
    short IConvertible.ToInt16(IFormatProvider provider)
    {
        return Convert.ToInt16(this.m_value);
    }2:decimal里面也与这样的受保护的实现方法short IConvertible.ToInt16(IFormatProvider provider)
    {
        return Convert.ToInt16(this);
    }
    但也还有如下的 静态方法。
    public static short ToInt16(decimal value)
    {
        int num = ToInt32(value);
        if ((num < -32768) || (num > 0x7fff))
        {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
        }
        return (short) num;
    }看来因为类型都继承了接口,内部是必须实现接口的,但接口都是调用Conver类中的实现。
    而对于基元类型,没有定义ToXXX()方法,所以只能通过调用Conver类中的方法。
    对于其他如Decimal类型,因为内部提供了公有静态方法,所以可以直接通过类型调用ToXXX()方法实现。3:在看下Convert中的实现,实际他是调用decimal内部实现
    public static short ToInt16(decimal value)
    {
        return decimal.ToInt16(decimal.Round(value, 0));
    }
    4:而对于那些内部没有实现ToXXX方法的,是在Convert中实现的。
    public static short ToInt16(int value)
    {
        if ((value < -32768) || (value > 0x7fff))
        {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
        }
        return (short) value;
    }看完上面基本明白了,
    1:对IConvertible接口方法的实现,都是调用Convert类的方法。
    2:基元类型的转换的实现基本都在Convert里面,而内部没有实现,所以要通过Convert实现转换。
    3:对于内部实现了的ToXXX()方法的(比如Decimal),我们可以直接调用此静态方法,也可以通过Convert的方法(其实他也是调用内部实现了的ToXXX()方法)
    4:对于采用强制类型转换,基元类型会自动产生IL指令,而其他类型则调用转换操作符方法。不知道我说的对不对!?