淺談C#基元類型及常見問(wèn)題解答
什么是C#基元類型?
我想并不是每一位開發(fā)者都清楚的,有部分的朋友只知道怎么在工作中應(yīng)用它(例如int,string)。如果一個(gè)編程基礎(chǔ)比較扎實(shí)的朋友來(lái)說(shuō)當(dāng)然不在話下,就不說(shuō)別人,拿我自己來(lái)說(shuō),編程三年多,我都不太關(guān)心什么是基元類型,它有什么用,其實(shí)不知道這些對(duì)工作也不會(huì)產(chǎn)生決定性的影響。如果你不知道基類型的概念,但會(huì)用int,float之類,對(duì)平常工作是沒有太大影響的。但如果有人和你討論這些東西時(shí),還是覺的非常有必要對(duì)其進(jìn)行了解和學(xué)習(xí)。
比較常見的問(wèn)題,其中一個(gè)也是最近園友說(shuō)過(guò)的:
第一:int和int32有啥區(qū)別?
第二:string和String又有啥區(qū)別?
像很多園友回復(fù)的一樣,對(duì)這些東西有時(shí)不必要太過(guò)較真,但既然有這樣的問(wèn)題,總規(guī)要有答案了。這里我列出以下幾種申明一個(gè)整形變量的代碼:
- //最簡(jiǎn)單
- int a = 0;
- //較簡(jiǎn)潔的
- Int32 b=0;
- //不簡(jiǎn)潔的
- int c = new int();
- //最不簡(jiǎn)潔
- System.Int32 d = new System.Int32();
我們?cè)賮?lái)看下這些代碼生成的IL代碼:
結(jié)論:它們都是申明一個(gè)int32類型的變量,并且對(duì)其進(jìn)行了初始化。至于這是什么原因呢?這里就只能用基元類型來(lái)解釋了。我們來(lái)看下C#的基元類型和FCL以及CLS的部分關(guān)系。從下面的表中可以看出:
- .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中。這里足以解釋上面四種創(chuàng)建變量的結(jié)果為什么是一樣的原因。
2:string和System.Sting其實(shí)并無(wú)實(shí)質(zhì)的區(qū)別,說(shuō)的簡(jiǎn)單點(diǎn),string是String的一個(gè)別名。
using方式理解基元類型和FCL的關(guān)系 : 可以利用using語(yǔ)句來(lái)實(shí)現(xiàn):
- using sbyte=System.SBYTE;
- using int=System.Int32;
- using string=System.String;
FCL類型之間的轉(zhuǎn)換:我們知道在FCL類型變量之間可以進(jìn)行相關(guān)的轉(zhuǎn)換,例如:
- Int32 i=0;
- Int64 j=i;//隱式轉(zhuǎn)換成Int64
下面是對(duì)應(yīng)的IL代碼:我們可以看出有一人conv.i8操作,這里就是數(shù)據(jù)類型的轉(zhuǎn)換。
- .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的角度來(lái)講,這種轉(zhuǎn)換并不是"太正常":
1:Int32和Int64是兩種不同的數(shù)據(jù)類型;
2:兩者之間并不存在繼承關(guān)系。
問(wèn)題:為什么兩者之間能夠正常轉(zhuǎn)換呢?也是因?yàn)榛愋秃偷年P(guān)系。
C#基元類型之間的轉(zhuǎn)換提供了兩種方式:
第一:隱式轉(zhuǎn)換,如果兩個(gè)C#基元類型之間是類型安全的,則可以直接進(jìn)行轉(zhuǎn)換;
第二:顯示轉(zhuǎn)換,C#基元類型之間是非安全的,需要強(qiáng)制轉(zhuǎn)換。
【編輯推薦】