最近看了下类型转换我想知道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()方法?
所以在使用(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()方法?
并且是收保护的方法。内部也没有转换操作符。
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指令,而其他类型则调用转换操作符方法。不知道我说的对不对!?