那结构与类有什么相似之处与不同之处呢?
结构和类,
相同之处是都含有成员,包括构造函数、方法、属性、字段、常量、枚举和事件,都可以实现接口,都有共享的构造函数,都能对成员进行封装。
没错都有构造函数,那结构的构造函数是什么,结构难道也可被实例化成对象?
看这一段代码:
怎么样,是不是很好奇,明明只定义一个带参数的构造函数,intB 的实例化我们可以明白,但是是 intA 怎么也能通过编译器检测,给实例化呢?
是不是很好奇,结构怎么也能实例化成对象,和类很象呢!
原因是,每个结构都隐式地具有 Public 无参数实例构造函数也就是 Public Sub New(),该构造函数能产生结构的默认值。所以你平时不写构造函数,也一样可以 New出一个结构来。
那结构和类在内存分配上难道也是 一样的吗?当然不一样,差别可就大了。
简单来说 ,结构是值类型,而类是引用类型。因此,结构使用堆栈分配,类使用堆(托管堆)分配。
示例:
结果如图:
这就是值类型和引用类型的差别。
不管后面定义多少个 class 类型的变量,只要不实例化,它们都只是在堆栈上划分各自的空间,来存储 class 对象的引用地址,而这每个不同名称的引用地址都指向同一个引用对象的实际值。所以,不管哪个 class 类型变量改变了值,它都会影响原始值。
说得更清楚一点,类作为引用类型,是存储在堆上,只能通过引用地址来访问它们,不能直接访问。
引用类型的变量总是包含该类型的值引用,或包含空引用。空引用不引用任何内容;除分配空引用外,对空引用进行的任何操作都是无效的。
引用类型的变量赋值只会创建引用的一个副本,而不是所引用的值的副本。它们实际上都是会指向同一块存储区的。
结构是直接存储在堆栈上,要么在数组中,要么在另一个类型中 。当包含结构实例的位置被销毁时,结构实例也会被销毁。值类型总是可以直接 访问。我们不能创建对值类型的引用,也不能引用已销毁的值类型实例。值类型的变量总是包含此类型的值。与引用类型不同,值类型的值不能为空引用,也不能引用派生相近程度较大的类型的对象。值类型的变量赋值会创建所赋的值的副 本,当然会新开辟一块内存区来保存值。
那它们还有什么区别没有呢?
当然有很多,比如所有的结构成员都默认为 Public,而类的变量和常量默认为 Private。其他的类成员默认为 Public;结构成员不能声明为 Protected,而类成员可以;结构过程不能处理事件,类过程可以;结构变量声明不能指定初始值、New 关键字或数组初始大小,类变量声明可以。
结构从不终止,所以公共语言运行库从不在任何结构上调用 Finalize 方法;类可由垃圾回收器终止,垃圾回收器会跟踪未完成的引用直到某个特定的实例,当检测到没有剩下的活动引用时, 垃圾回收器将在类上调用 Finalize。”
因为结构是值类型,是由系统统一管理内存,不是引用,所以不会对内存造成危害。
还有结构是不可继承的,而类可以继承。其实结构自身是从 ValueType 类隐式继承下来的。
数据类型可分为值类型和引用类型。值类型要么是堆栈分配的,要么是在结构中以内联方式分配的。引用类型是堆分配的,引用类型和值类型都是从最终的基类 Object 派生出来的。当值类型需要充当对象时 ,就在堆上分配一个包装,该包装能使值类型看上去像引用对象一样,并且将该值类型的值复制给它。该包装被加上标记,以便系统知道它包含一个值类型。这个过程程称为装箱,其反向过程程称为拆箱。装箱和拆箱能够使任何类型像对象一样进行处理。