C#基本数字数据类型一共有11种,其中8种整数类型(byte, sbyte, short, ushort, int, uint, long, ulong),3种可带小数类型(double, float, decimal).首先,我对8种整数类型做了如下测试:
class Program
{
public static byte _byte;
public static sbyte _sbyte;
public static short _short;
public static ushort _ushort;
public static int _int;
public static uint _uint;
public static long _long;
public static ulong _ulong;
public static byte _byte2;
public static short _short2;
public static uint _uint2;
public static long _long2;
static void Main(string[] args)
{
_byte = 20;
_sbyte = 20;
_short = 20;
_ushort = 20;
_int = 20;
_uint = 20;
_long = 20;
_ulong = 20;
_byte2 = (byte)20;
_short2 = (short)20;
_uint2 = 20U;
_long2 = 20L;
}
}
生成的IL代码如下:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 89 (0x59)
.maxstack 1
IL_0000: nop
IL_0001: ldc.i4.s 20
IL_0003: stsfld uint8 ConsoleApplication1.Program::_byte
IL_0008: ldc.i4.s 20
IL_000a: stsfld int8 ConsoleApplication1.Program::_sbyte
IL_000f: ldc.i4.s 20
IL_0011: stsfld int16 ConsoleApplication1.Program::_short
IL_0016: ldc.i4.s 20
IL_0018: stsfld uint16 ConsoleApplication1.Program::_ushort
IL_001d: ldc.i4.s 20
IL_001f: stsfld int32 ConsoleApplication1.Program::_int
IL_0024: ldc.i4.s 20
IL_0026: stsfld uint32 ConsoleApplication1.Program::_uint
IL_002b: ldc.i4.s 20
IL_002d: conv.i8
IL_002e: stsfld int64 ConsoleApplication1.Program::_long
IL_0033: ldc.i4.s 20
IL_0035: conv.i8
IL_0036: stsfld uint64 ConsoleApplication1.Program::_ulong
IL_003b: ldc.i4.s 20
IL_003d: stsfld uint8 ConsoleApplication1.Program::_byte2
IL_0042: ldc.i4.s 20
IL_0044: stsfld int16 ConsoleApplication1.Program::_short2
IL_0049: ldc.i4.s 20
IL_004b: stsfld uint32 ConsoleApplication1.Program::_uint2
IL_0050: ldc.i4.s 20
IL_0052: conv.i8
IL_0053: stsfld int64 ConsoleApplication1.Program::_long2
IL_0058: ret
} // end of method Program::Main
我们发现,_byte = 20 与 _byte = (byte)20 生成的代码一模一样,_long = 20 与 _long = 20L生成的代码也一模一样。因此,结合一些其他测试(这里省略) ,我们得出以下结论:
1、_byte = 20 与 _byte = (byte)20 的效益一样。
2、_long = 20 与 _long = 20L 的效益一样,20L中的“L”仅仅在编译中起作用。
3、编译器会自动检测直接赋的值是否超过该类型所能表示的最大范围. ( _byte = 256 会导致编译出错)
接下来我们对double,float,decimal进行测试:(注释的行表示会导致编译无法通过)
class Program
{
public static float _float;
public static double _double;
public static decimal _decimal;
static void Main(string[] args)
{
_float = 5;
//_float = 5.0;
_float = 5F;
//_float = 5M;
_double = 5;
_double = 5.0;
_double = 5F;
//_double = 5M;
_decimal = 5;
//_decimal = 5.0;
_decimal = 5.0M;
//_decimal = 5.0F;
}
}
IL代码如下:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 91 (0x5b)
.maxstack 6
IL_0000: nop
IL_0001: ldc.r4 5.
IL_0006: stsfld float32 ConsoleApplication1.Program::_float
IL_000b: ldc.r4 5.
IL_0010: stsfld float32 ConsoleApplication1.Program::_float
IL_0015: ldc.r8 5.
IL_001e: stsfld float64 ConsoleApplication1.Program::_double
IL_0023: ldc.r8 5.
IL_002c: stsfld float64 ConsoleApplication1.Program::_double
IL_0031: ldc.r8 5.
IL_003a: stsfld float64 ConsoleApplication1.Program::_double
IL_003f: ldc.i4.5
IL_0040: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0045: stsfld valuetype [mscorlib]System.Decimal ConsoleApplication1.Program::_decimal
IL_004a: ldc.i4.s 50
IL_004c: ldc.i4.0
IL_004d: ldc.i4.0
IL_004e: ldc.i4.0
IL_004f: ldc.i4.1
IL_0050: newobj instance void [mscorlib]System.Decimal::.ctor(int32,
int32,
int32,
bool,
uint8)
IL_0055: stsfld valuetype [mscorlib]System.Decimal ConsoleApplication1.Program::_decimal
IL_005a: ret
} // end of method Program::Main
结论:
1、跟整数类型不同,带小数类型在直接赋数值时必须指定相应数值类型 或 可由该默认数值类型隐式转化为该变量类型。
2、_float = 5 与 _float = 5F 的效率一样。"F" 同样只在编译中起作用。
3、decimal类型的赋值跟其它类型有些不同,查decimal的构造方法发现,它有9个公有构造方法。
以上就是我对数值类型的简单分析,如有不足或错误,欢迎大家指出。
附:
L 表示 long
D 表示 double
F 表示 float
M 表示 decimal
U 表示 uint
UL 表示 ulong