【IT168技术】本文主要介绍讲述CLR via C#中关于类型的一些知识包括以下内容:基本类型、引用类型和值类型、值类型的装箱与拆箱。
1.基元类型
编译器能够直接支持的数据类型叫做基元类型。例如int, string等。基元类型和.NET框架类库FCL存在着直接的映射关系。
string和String?
面试的时候曾经被问到过这个问题,C#中的基元类型string实际上对应了System.String(FCL)类型,所以两者使用的时候没有什么不同。
类型转换
编译器能够在基元类型之间进行显式或隐式转换。如果转换是安全的,也就是转换过程不会造成数据丢失,则可以直接采用隐式转换。如果是不安全的,则必须采用显式转换。
Int32 a=5;
Int64 b=a;
Int32 c=(Int32)b;
Int64 b=a;
Int32 c=(Int32)b;
2. 引用类型和值类型
引用类型和值类型的区别:
结构体直接继承自System.ValueType;而枚举直接继承自System.Enum, Enum类又直接继承自System.ValueType。
下面通过例子看一下他们的区别:
首先定义类和结构体:
class SomeRef { public Int32 x; }
struct SomeVal { public Int32 x; }
struct SomeVal { public Int32 x; }
SomeRef r1 = new SomeRef(); // 分配到堆
SomeVal v1 = new SomeVal(); // 分配到栈
r1.x =5; // 所引用的堆空间内数据修改
v1.x =5; // 直接在栈上复赋值
Console.WriteLine(r1.x); // "5"
Console.WriteLine(v1.x); // "5"
SomeRef r2 = r1; //只把指针复制给了r2
SomeVal v2 = v1; // 在栈上分配空间,并且将变量内容进行复制
r1.x = 8; // r1指向(也是r2指向)的内容修改
v1.x = 9; // 只修改v1内容,v2内容不会受影响
Console.WriteLine(r1.x); // "8"
Console.WriteLine(r2.x); // "8"
Console.WriteLine(v1.x); // "9"
Console.WriteLine(v2.x); // "5"
SomeVal v1 = new SomeVal(); // 分配到栈
r1.x =5; // 所引用的堆空间内数据修改
v1.x =5; // 直接在栈上复赋值
Console.WriteLine(r1.x); // "5"
Console.WriteLine(v1.x); // "5"
SomeRef r2 = r1; //只把指针复制给了r2
SomeVal v2 = v1; // 在栈上分配空间,并且将变量内容进行复制
r1.x = 8; // r1指向(也是r2指向)的内容修改
v1.x = 9; // 只修改v1内容,v2内容不会受影响
Console.WriteLine(r1.x); // "8"
Console.WriteLine(r2.x); // "8"
Console.WriteLine(v1.x); // "9"
Console.WriteLine(v2.x); // "5"
看看下图的内存分配情况,就一目了然了。