CLR Via C#: 基元类型、引用类型和值类型
编程语言的基元类型 - 编译器直接支持的数据类型
基元类型直接映射到Framework类库(FCL)中存在的类型
int a1 = 0; System.Int32 a2 = 0; int a3 = new int(); System.Int32 a4 = new System.Int32();
C#基元类型:
- sbyte
- byte
- short
- ushort
- int
- uint
- long
- ulong
- char
- float
- double
- bool
- decimal
- string
- object
- dynamic
编译器能执行基元类型之间的隐式或显示转换。只有在转换“安全”的时候,C#允许隐式转换。所谓“安全”,是指不会发生数据丢失的情况。“不安全”意味着在转换之后,有可能丢失精度或者数量级。
除了转型,基本类型还能写成文本常亮。
Console.WriteLine(123.ToString() + 456.ToString()); //"123456"
checked和unchecked基元类型操作
对基元类型执行的许多算术运算都可能造成溢出。
Byte b = 100; b = (Byte)(b + 200); Console.WriteLine(b); // 44 Console.ReadLine();
让C#编译器控制溢出的一个办法是使用/checked+编译器开关。这个开关只是编译器在生成代码是,使用加、减、乘和转换指令的溢出检测版本。除了全局性的打开或关闭溢出检测,程序员还可以在代码的指定区域控制溢出检测。
UInt32 invalid = unchecked((UInt32)(-1)); Console.WriteLine(invalid); Console.ReadLine();
UInt32 invalid = checked((UInt32)(-1)); // OverflowException Console.WriteLine(invalid); Console.ReadLine();
checked { Byte b = 100; b = (Byte)(b + 200); }
引用类型和值类型
- 引用另一篇博客中的一句话:值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。
- 值类型的实例一般在线程栈上分配。在代表值类型实例的一个变量中,并不包含一个指向实例的指针。相反,变量中包含了实例本身的字段。
- 在文档中查看一个类型时,任何称为“类”的类型都是引用类型,文档将所有值类型都成为结构或枚举
- 引用类型,string和class统称为引用类型,当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用new创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小空间中。
- 两者的主要区别:
-
- 值类型的内存空间分配在栈上;而引用类型的内存空间分配在堆上
- 栈的内存分配时自动释放;而堆的内存是有GC(垃圾回收)来释放
- 值类型存取速度快,引用类型存取速度慢
- 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用
- 值类型继承自System.ValueType (ValueType是继承自System.Object的),引用类型继承自System.Object
- 引用类型的Equals方法默认比较地址,而值类型的默认比较值
- 引用类型可以派生出新的类型,而值类型不能
- 引用类型可以设置为null值,值类型一般不能(只有Nullable<T>可以设置为null值)
- 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制对象
- 值类型一旦定义,则不可以变
class Program { static void Main(string[] args) { SomeRef r1 = new SomeRef(); //在堆上分配 SomeVal v1 = new SomeVal(); //在栈上分配 r1.x = 5; v1.x = 5; Console.WriteLine(r1.x); Console.WriteLine(v1.x); SomeRef r2 = r1; // 5 SomeVal v2 = v1; // 5 r1.x = 8; v1.x = 9; Console.WriteLine(r1.x); // 8 Console.WriteLine(r2.x); // 5 Console.WriteLine(v1.x); // 9 Console.WriteLine(v2.x); // 5 Console.ReadLine(); } } //引用类型,由于使用了‘class’ class SomeRef { public Int32 x; } //值类型,由于使用了'struct' struct SomeVal { public Int32 x; }
posted on 2022-03-08 14:52 LilianChen 阅读(57) 评论(0) 编辑 收藏 举报