C#中基础的基础(Primitive,Reference,value Types)
Important:A solider understanding of basal concepts is critical to any .NET Framework developer’s long-term success.Turst me: having a solid grasp of these concepts will allow you to build efficient applications faster and easier.
Any data types the complier directly supports are called primitive types.C# has 15 primitive types: sbyte,byte,short,ushort,int,uint,long,ulong ||char ||float(System.Single),double,decimal ||bool || object string .
In c#,the string(a keyword) maps exactly to System.String(a FCL Type),there is no difference and either can be used.
Look at this code:
Byte b =100;
b = (Byte) (b+200);// b now contains 44
Byte cast on the second line of the preceding code is required,because the CLR perfor arithmetic operations on 32-bit and 64-bit values only.
Different languages handle overflow in different ways.C and C++ don’t consider overflows to be an error and allow the value to wrap,the application continues running with its fingers crossed.Visual Basic,on the other hand,always considers overflows as errors and throws an System.OverflowException exception when it detects an overflow.
C# allows the programmer to decide how overflows should be handled.By default,overflow checking is turned off.One way to get the c# compiler to control overflows is to use the /checked+ command-line switch.The code executes more slowly because the CLR is checking these operations to see whether an overflow will occur.
The checked operator and statement affect only which versions of the add, subtract , multiply , and data conversion IL instructions are produced, calling a method within a checked operator or statement has no impact on the method. The following code demonstrates:
checked {//Assume Somethod tries to load 400 into a Byte. SomeMethod(400); //SomeMethod might or might not throw an OverflowException. //It would if Somethod were compiled with checked instructions. }
The System.Decimal type is a very special type.Although many programming languages(c# and Visual Basic included) consider Decimal a primitive type,the CLR does not. This means that the CLR doesn’t hava IL instructions that know how to manipulate a Decimal value. So when you compile code using Decimal values,the compiler generates code to call Decimal’s members to perform the actual operations.This means that manipulating Decimal values is slower than manipulating CLR primitive values. Also,because there are no IL instructions for manipulating Decimal values,the checked and unchecked operators,statements,and compiler command-line options hava no effect.Operations on Decimal values always throw an OverflowException if the operation can’t be performed safely.
Boxing and Unboxing value types
It’s possible to convert a value type to a reference type using a mechanism called boxing.
Internally,Boxing:
1.Memory is allocated from the managed heap.The amount of memory allocated is the size the value type requires plus any additional overhead to consider this value type to be a true object.The additional overhead includes a method table pointer and a SyncBlockIndex.
2.The value type’s fields are copied to the newly allocated heap memory.
3.The address of the object is returned.
In contrast,internally,unboxing:
1.If the reference is null, a NullreferenceException is thrown.
2.If the reference doesn’t refer to an object that is a boxed value of the desired value type,an InvalidCastException exception is thrown.
3.A pointer to the value type contained inside the object is returned.The value type that this pointer refers to doesn’t konw anything about the usual overhead associated with a true object:a method table pointer and a SyncBlocdIndex.In effect,the pointer refers to the unboxed portion in the boxed object.
So,unboxing is not the exact opposite of boxing.The unboxing operation is much less costly than boxing.Unboxing is really just the operation of obtaining a pointer to the raw value type(data fields) contained within an object.So,unlike boxing,unboxing doesn’t involve the copying of any bytes in memory.However,an unboxing operation is typically followed by copying the fields,making these two operations the exact opposite of a boxing operation.
Unboxed value types are lighter-weight types than reference types for two reasons:
a.They are not allocated on the managed heap;
b.They don’t have the additional overhead members that every object on the heap has:a method table pointer and a SyncBlockIndex.
[From <applied.Microsoft.NET.Framework.Programming>]