数据类型
C#中的数据类型分为两种:值类型和引用类型。值类型包括:int, float, double, char, struct, enum, bool, long等。其中struct比较特殊。struct包含字段,但字段不能赋予初始值,而是由带参构造函数传递进去。struct不能使用无参构造函数。因为struct是值类型,所以他们之间的赋值属于深度拷贝,也就是复制所有内容。struct和类有些相似,使用时容易混淆。在内存分配上二者有本质区别,这样是值类型与引用类型的本质区别。值类型都是分配线程栈上的,而引用类型分配到托管堆上。栈在内存中占比不大,属于稀缺资源,所以如果大量使用struct必会造成内存的不足,影响性能。因此,复杂的数据结构还是用引用类型比较合适。类和struct的具体不同可以参照文章C#深入struct。
说到引用类型,再熟悉不过了,包括数组,delegate, string, class,interface,抽象类等。这些类型实际上存放在托管堆上,而在栈上有个地址指向他们,那么栈上的这个地址就是个refrence。值得注意的是数组和string,数组继承自system.array。所以我们实例化一个数组时用new。例如:int[] arr = new int[5]。string 也是个应用类型,不过他是不可变长的(immutable)。每次给同一个string的变量赋值,系统都会申请新的空间。这势必会比较浪费,所以,如果你的string总是变来变去,还是用StringBuilder比较好,因为他是可变长的。
值类型与引用类型之间是可以转化的,俗称装箱和拆箱。装箱(boxing)就是把值类型包装成引用类型。拆箱是相反的行为,即把引用类型转化成值类型。装箱不会产生异常,而拆箱则有可能异常。装箱往往是不自觉的发生。比如:string str = "10"+10; 这条语句就会产生装箱操作,即把值类型10变成了引用类型string。如果这种语句用的多了,性能会下降,因为装箱很费时间和空间。
在.net 4.o中加入了可取空值的值类型。比如int?, double?等。这些都是特殊泛型类System.Nullable<T>的缩写。例如:int? number = null 等同于 System.Nullable<int> number = null。这种类型在读取数据库字段的时候很有用。因为有的时候,数据库里的某些字段是可以为空的,每次读取都判断是很费时间的,用这种可空类型读取就省事了。于是乎,微软又出了个??操作符来配合可空类型。如果你想在某个值为空的时候用0或者其他的数代替,可以这样写:int result = op ?? 0; 这句话的意思是,如果op为null,则result就被赋予0,否则还是用op的值。
还有一种类型用的很广泛,那就是泛型。泛型是个好东西,他让我们写通用的类或者方法更加方便了。如果你的方法逻辑相同,只是传递的值类型不同,那么可以用泛型来写。比如:public T GetMaxValue(T[] number)。再比如:public class MaxMin<T> where T:IComparable<T>。有了泛型,就再也不用写那些无聊的重复代码了。
好了,关于数据类型的部分就先写这么多,已后有时间再追加。如果有什么地方写的不对,请指正,多谢。