淺談C#基元類型及常見問題解答
什么是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#基元類型之間是非安全的,需要強制轉換。
【編輯推薦】