类型
bool
- System.Boolean的别名。
- 只需要1 bit 存储空间,但运行时会使用1 byte 内存(运行时和处理器可以高效操作的最小的块)。
- 针对数组,Framework 提供了 BitArray 类,(System.Collections),在这里每个 bool 值只占用1 bit 内存。
string
逐字字符串 verbatim string literal
- 使用 @ 做前缀(写在双引号外面)。
- 不支持转义字符(例: string a1 = “\\server\fileshare\helloworld.cs”; string a2 = @“\server\fileshare\helloworld.cs”;两个字符串的值相同)。
- 支持多行字符串。
- 在字符串里面输入双引号时,需输入两次双引号(例:string xml = @“<customer id=”“123"”>";)。
字符串插值 string interpolation
- C# 6新特性。
- 使用 $ 做前缀(写在双引号外面)。
- 可包含表达式,在 {} 内(例:int x=4; Console.WriteLine($“A square has {x} sides”);)。
- 任何C#表达式都可以出现在{}内,会调用ToString或等效方法。
- 可以改变表达式的显示格式,使用 : ,后面跟着格式化字符串(例:string s = $“255 in hex is {byte.MaxValue:X2}”;)。
- 默认只支持单行,除非使用@,$ 需在 @ 前。
- 在字符串里面输入 { 时,需输入 {{ 。
数组
- 数组的元素存储在连续的内存块里,读取效率高。
- 所有的数组都继承于 System.Array 类。
- 一旦数组被创建,那么其长度不可改变。
- 创建数组时,所有的元素都会被初始化,其值为该类型的默认值。
值类型 vs 引用类型
- 值类型:每个元素都作为数组的一部分进行分配内存。
- 引用类型:创建数组时就是创建了一堆null引用(建议对元素是引用类型的数组初始化后对元素都进行初始化)。
矩形数组 rectangular array
- 代表n维内存块。
- 使用逗号来分割维度(例:int[,] matrix = new int[3,3];)。
- GetLength方法可返回指定维度的长度。
交错数组 jagged array
- 元素类型为数组的数组。
- 使用连续的中括号来声明和代表不同的维度(例:int [][] matrix = new int[3][];)。
- 内层维度并没有具体指明,内层维度的数组可以是任意长度。
边界检查
- 所有数组的索引都会被运行时检查。
- 如果使用了不合理的索引,抛出IndexOutOfRangeException。
- 边界检查对性能的影响很小,JIT编译器可执行一些优化(例:进入循环前预先对所有的索引进行安全检查,避免在迭代中检查)。
- C# 提供了“unsafe”代码,可以绕过边界检查。
操作符
== 、!=
- 对于值类型,该操作符是比较它们的值。
- 对于引用类型,默认情况下,是比较他们的引用。
&&、||
- 符合短路机制。
- 可避免 NullReferenceException。
&、|
- 没有短路机制。
- 很少用于条件判断。
- 当使用于数值的时候,& 和 | 执行的是按位操作。
Stack 栈 vs Heap 堆
- Stack(一块内存)存储本地变量和参数,随着函数的进入和退出,Stack会随之增大和缩小。
- Heap(一块内存),对象所在的地方(引用类型的实例);当新的对象被创建后,它就会被分配在Heap上,到该对象的一个引用被返回;程序执行时,随着新对象的不断创建,heap会被慢慢的填满,一旦一个对象不再被任何“存活”的东西所引用,运行时的GC会周期性的把对象从heap上释放出来,所以不会导致内存耗尽。
内存
值类型的实例(和对象的引用)会放在变量声明时所在的内存块里。
GC
C#中不可以显式的删除对象,无引用的对象会逐渐被GC收集。
static字段
存储在Heap上,会存活到应用程序域停止。
确定赋值 Definite Assignment
- 本地变量在被读取之前必须被赋值。
- 当方法被调用的时候,函数的参数必须被提供(除非是可选参数)。
- 其他的变量(字段、数组元素)会被运行时自动初始化。
参数传递的方式
Parameter modifier | Passed by | Variable must be definitely assigned |
---|---|---|
(None) | Value | Going in |
ref | Reference | Going in |
out | Reference | Going out |
默认情况
值类型
按值传递实参,当传进方法时形参把实参的值复制一份。
引用类型
按值传递引用类型的实参,形参复制的是引用,不是对象。
ref
想要按引用传递,可以使用ref参数修饰符。
out
进入函数前不需要被赋值,离开函数前必须被赋值。通常用来从方法返回多个值。
从C# 7 开始,调用方法时,可以使用 out 临时声明变量。当调用的方法有多个 out 参数且不需要使用其中的一些 out 参数时,可以使用下划线 “_” 来 discard(弃用)它们。