什么是C#基元类型?
我想并不是每一位开发者都清楚的,有部分的朋友只知道怎么在工作中应用它(例如int,string)。如果一个编程基础比较扎实的朋友来说当然不在话下,就不说别人,拿我自己来说,编程三年多,我都不太关心什么是基元类型,它有什么用,其实不知道这些对工作也不会产生决定性的影响。如果你不知道基类型的概念,但会用int,float之类,对平常工作是没有太大影响的。但如果有人和你讨论这些东西时,还是觉的非常有必要对其进行了解和学习。
比较常见的问题,其中一个也是最近园友说过的:
第一:int和int32有啥区别?
第二:string和String又有啥区别?
像很多园友回复的一样,对这些东西有时不必要太过较真,但既然有这样的问题,总规要有答案了。这里我列出以下几种申明一个整形变量的代码:
- //最简单
- int a = 0;
- //较简洁的
- Int32 b=0;
- //不简洁的
- int c = new int();
- //最不简洁
- System.Int32 d = new System.Int32();
我们再来看下这些代码生成的IL代码:
结论:它们都是申明一个int32类型的变量,并且对其进行了初始化。至于这是什么原因呢?这里就只能用基元类型来解释了。我们来看下C#的基元类型和FCL以及CLS的部分关系。从下面的表中可以看出:
- .method private hidebysig static void Main(string[] args) cil managed
- {
- .entrypoint
- // 代码大小 10 (0xa)
- .maxstack 1
- .locals init ([0] int32 a,
- [1] int32 b,
- [2] int32 c,
- [3] int32 d)
- IL_0000: nop
- IL_0001: ldc.i4.0
- IL_0002: stloc.0
- IL_0003: ldc.i4.0
- IL_0004: stloc.1
- IL_0005: ldc.i4.0
- IL_0006: stloc.2
- IL_0007: ldc.i4.0
- IL_0008: stloc.3
- IL_0009: ret
- } // end of method Program::Main
C# Primitive Typ | FCL Type | CLS-Compliant |
sbyte | System.SBte | NO |
byte | System.Byte | YES |
short | System.Int16 | YES |
ushort | System.UInt16 | NO |
int | System.Int32 | YES |
uint | System.UInt32 | NO |
long | System.Int64 | YES |
ulong | System.UInt64 | NO |
char | System.Char | YES |
float | System.Single | YES |
double | System.Double | YES |
decimal | System.Decimal | YES |
object | System.Object | YES |
string | System.Strign | YES |
1:int被映射到FCL中的System.Int32中。这里足以解释上面四种创建变量的结果为什么是一样的原因。
2:string和System.Sting其实并无实质的区别,说的简单点,string是String的一个别名。
using方式理解基元类型和FCL的关系 : 可以利用using语句来实现:
- using sbyte=System.SBYTE;
- using int=System.Int32;
- using string=System.String;
FCL类型之间的转换:我们知道在FCL类型变量之间可以进行相关的转换,例如:
- Int32 i=0;
- Int64 j=i;//隐式转换成Int64
下面是对应的IL代码:我们可以看出有一人conv.i8操作,这里就是数据类型的转换。
- .method private hidebysig static void Main(string[] args) cil managed
- {
- .entrypoint
- // 代码大小 7 (0x7)
- .maxstack 1
- .locals init ([0] int32 i,
- [1] int64 j)
- IL_0000: nop
- IL_0001: ldc.i4.0
- IL_0002: stloc.0
- IL_0003: ldloc.0
- IL_0004: conv.i8
- IL_0005: stloc.1
- IL_0006: ret
- } // end of method Program::Main
分析:从OO的角度来讲,这种转换并不是"太正常":
1:Int32和Int64是两种不同的数据类型;
2:两者之间并不存在继承关系。
问题:为什么两者之间能够正常转换呢?也是因为基元类型和的关系。
C#基元类型之间的转换提供了两种方式:
第一:隐式转换,如果两个C#基元类型之间是类型安全的,则可以直接进行转换;
第二:显示转换,C#基元类型之间是非安全的,需要强制转换。
【编辑推荐】