您的位置:首页 > 编程语言 > C#

C# 类型基础

2008-08-03 13:56 197 查看

引言

本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制。复制又分为了浅度复制(Shallow Copy)和深度复制(Deep Copy),浅度复制 和 深度复制又是以 如何复制引用类型成员来划分的。由此又引出了 引用类型和 值类型,以及相关的对象判等、装箱、拆箱等基础知识。

于是我干脆新起一篇,从最基础的类型开始自底向上写起了。我仅仅想将对于这个主题的理解表述出来,一是总结和复习,二是交流经验,或许有地方我理解的有偏差,希望指正。如果前面基础的内容对你来说过于简单,可以跳跃阅读。

值类型 和 引用类型

我们先简单回顾一下C#中的类型系统。C# 中的类型一共分为两类,一类是值类型(Value Type),一类是引用类型(Reference Type)。值类型 和 引用类型是以它们在计算机内存中是如何被分配的来划分的。值类型包括 结构和枚举,引用类型包括类、接口、委托 等。还有一种特殊的值类型,称为简单类型(Simple Type),比如 byte,int等,这些简单类型实际上是FCL类库类型的别名,比如声明一个int类型,实际上是声明一个System.Int32结构类型。因此,在Int32类型中定义的操作,都可以应用在int类型上,比如 “123.Equals(2)”。

所有的 值类型 都隐式地继承自 System.ValueType类型(注意System.ValueType本身是一个类类型),System.ValueType和所有的引用类型都继承自 System.Object基类。你不能显示地让结构继承一个类,因为C#不支持多重继承,而结构已经隐式继承自ValueType。

NOTE:堆栈(stack)是一种后进先出的数据结构,在内存中,变量会被分配在堆栈上来进行操作。堆(heap)是用于为类型实例(对象)分配空间的内存区域,在堆上创建一个对象,会将对象的地址传给堆栈上的变量(反过来叫变量指向此对象,或者变量引用此对象)。

1.值类型

当声明一个值类型的变量(Variable)的时候,变量本身包含了值类型的全部字段,该变量会被分配在线程堆栈(Thread Stack)上。

假如我们有这样一个值类型,它代表了直线上的一点:

public struct ValPoint {

public int x;

public ValPoint(int x) {

this.x = x;

}

}

当我们在程序中写下这样的一条变量的声明语句时:

ValPoint vPoint1;
实际产生的效果是声明了vPoint1变量,变量本身包含了值类型的所有字段(即你想要的所有数据)。

// 将要进行 浅度复制 的对象,注意为 引用类型

// 定义一个引用类型成员

// 定义一个值类型成员

输出为:

Original line.rPoint.x = 1

Cloned newLine.rPoint.x = 1

Original line.rPoint.x = 10

Cloned newLine.rPoint.x = 1

可见,两个对象的引用成员已经分离,改变原对象的引用对象的值,并不影响复制后的对象。

这里需要注意:如果想将对象进行序列化,那么对象本身,及其所有的自定义成员(类、结构),都必须使用Serializable特性进行标记。所以,如果想让上面的代码运行,我们之前定义的类都需要进行这样的标记:

[Serializable()]

public class RefPoint { /*略*/}
NOTE:关于特性(Attribute),可以参考 .Net 中的反射(反射特性) 一文。

总结

本文简单地对C#中的类型作了一个回顾。

我们首先讨论了C#中的两种类型--值类型和引用类型,随后简要回顾了装箱/拆箱 操作。接着,详细讨论了C#中的对象判等。最后,我们讨论了浅度复制和 深度复制,并比较了它们之间不同。

希望这篇文章能给你带来帮助!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: