c#语言系列讲座(14) 结 构

转载 2004年09月01日 12:31:00
结 构

类为采用面向对象方式构建可复用组件提供了支持,但有时候我们希望能够获得一种像系统内建的基本类型一样可以方便快速地为之分配内存,并且没有继承引用等负担的轻量级的数据类型。C#中的自定义结构类型为我们提供了这样的实现方式,它尤其适用于构建一些比较小的数据结构。

结构和类非常相似,它们都可以包含域、方法、属性、事件、索引等成员,结构也可以实现多个接口。但结构和类也有很大差异,最典型的是结构为值类型,而类为引用类型。值类型使得结构变量本身包含着结构的数据,这些数据被分配在栈上,而不是像类等引用类型那样分配在托管堆上。值类型是结构最核心的性质,由此衍生出了它的种种行为。结构的赋值是特别需要注意的,看下面的代码:

using System;

struct sPoint{ //点结构

public int x, y;

public sPoint(int x, int y) {

this.x = x;

this.y = y;

}

}

class Test{

static void Main() {

sPoint spa=new sPoint(10,20);//点结构

sPoint spb=spa;

//点结构赋值

spb.x=0;

Console.WriteLine(spa.x+“,”+spa.y);//10,20

Console.WriteLine(spb.x+“,”+spb.y);//0,20

}

}

对结构的赋值导致结构内数据的拷贝,而非引用句柄的拷贝!同样的,作为参数或返回值传递的结构也是对其数据成员的一份新的拷贝。

结构实例构造器和实例成员函数中的this也和类中的this含义有所不同。在类中,this本质上是一个引用句柄值,它不可以再被赋值;而在结构中,this更像一个结构类型的变量,它可以被赋值。

结构类型的缺省值是将它所有的值类型的数据成员设置为对应值类型的缺省值,将其引用类型的数据成员设置为null,而类的缺省值为null。由于结构变量本身总包含着它的数据,不可以将结构变量赋值为null——结构没有引用句柄的概念,自然不能有null值!值类型的缺省值规则使得结构不可以再声明无参数的构造器。对于实例成员,结构不允许在声明的同时进行初始化。但对于静态成员则没有此规定,可以声明实现无参数的静态构造器。结构中不允许声明实现析构器,这是由它的栈分配性质决定的。

一个类变量可以在编译时被隐含地转化为该类的继承基类(如object)变量或其实现的接口类型变量,运用明晰转型也可以逆向进行。那么作为值类型的结构变量如何被转化为object变量或其实现的接口变量?C#引入一种称做box和unbox的操作来进行这种双向的转换。box和unbox操作为值类型和引用类型之间提供了一个转换的桥梁,使得C#中的数据类型得以统一。

当结构变量需要被转换为object变量或其实现的接口变量时,box操作在托管堆上为object变量或接口变量分配空间,并把结构变量的数据拷贝到相应的位置。相反,当object变量或其实现的接口变量被转换为结构变量时,unbox操作使得相应的数据从托管堆内拷贝到结构变量所在的栈上。

枚 举

枚举类型是C#中又一种轻量级的值类型,C#用枚举来表达一组特定值的集合行为,比如Windows窗体可选的状态、按钮控件的风格等。下面的程序代码展示了典型的枚举用法:

public enum WritingStyle{

Classical,

Modern,

Elegant,

}

class Essay {

public void Write(WritingStyle writingStyle) {

switch (writingStyle){

case WritingStyle.Classical:

break;

case WritingStyle.Modern:

break;

case WritingStyle.Elegant:

break;

default:

throw(new System.ArgumentException(“Invalid Writing Style”));

}

}

}

注意上面的枚举符号Classical、 Modern、Elegant之间用逗号“,”而不是分号“;”来分隔,其中最后一个枚举值Elegant之后可以省去逗号分隔符。

和结构一样,C#中的枚举不允许有自己的继承父类System.Enum; 同样的,枚举不能被继承,也没有“abstract”之说。System.Enum类为枚举类型提供了很多好用的功能操作,比如可以通过GetName方法得到声明枚举值的字符串符号表示。下面的例子显示了一些比较常用的操作:

using System;

public enum WritingStyle{

Classical,

Modern,

Elegant,

}

class Test {

public static void Main() {

WritingStyle dw=WritingStyle.Modern;

Console.WriteLine(Enum.GetName(typeof(WritingStyle),dw));

Console.WriteLine(dw.ToString());

Console.WriteLine(Enum.GetUnderlyingType(typeof(WritingStyle)));

}

}

C#的枚举和整数值之间严格区分,比如我们不能在上面的代码中做“dw=1”类似的赋值。但每个枚举值却的的确确都有一个整数类型的数值相对应,而且可以转换,只不过这种转换必须用明晰的转型语法来表达。我们知道在C#中整数类型有byte、 sbyte、 short、 ushort、int、uint、long和ulong共八种,那么C#的枚举值对应的是哪一种整数类型呢?它关系到我们的枚举类型能够容纳的枚举值的数量。实际上C#枚举类型支持这八种整数类型的任何一种,根据需要可以在声明枚举类型的时候来指定,如“public enum WritingStyle :byte”就指定了它的枚举值的整数类型为byte。该类型可以通过上面所述的Enum.GetUnderlyingType方法来获得。如果不明确指定,C#将默认采用int类型作为枚举数值的类型。另外,枚举值也拥有像整数那样的比较、逻辑、算术等操作行为。

火车购票问题(2016CCF)

问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。 假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排 ...
  • cs9426478
  • cs9426478
  • 2016年09月14日 21:22
  • 4103

数据结构C++语言描述专题系列 (三) 队列

1、队列及其实现队列的定义:在表的一端(rear)进行输入,在另一端(front)进行输出操作的表。 队列的特点:先进先出(FIFO)。 队列的抽象数据类型 ADT Queue is Dat...
  • sealeader
  • sealeader
  • 2015年12月08日 11:15
  • 3120

【数据科学】《微软亚洲研究院大数据系列讲座》1-大数据研究现状及未来趋势

课程目录: 1.1 什么是大数据 1.2 为什么大数据是当前热点 1.3 新的计算基础设施和工具 1.4 课程简介 1.5 基础设施、机器学习和可视化 1.6 大数据与传统商业智能的区别1...
  • future_todo
  • future_todo
  • 2015年11月19日 17:06
  • 1441

C#语言系列讲座18讲

  • 2008年06月27日 23:48
  • 156KB
  • 下载

C#语言系列讲座

  • 2007年09月14日 08:39
  • 14KB
  • 下载

C#线程系列讲座(5):同步技术之Monitor

转自:http://www.cnblogs.com/nokiaguy/archive/2008/07/31/1257625.html  在上一讲介绍了使用lock来实现线程之间的同步。实际上...
  • KAIFEIXIONGDI
  • KAIFEIXIONGDI
  • 2012年04月14日 15:52
  • 471

C#线程系列讲座(4):同步与死锁

虽然线程可以在一定程度上提高程序运行的效率,但也会产生一些副作用。让我们先看看如下的代码:     class Increment      {         private int ...
  • r798303142b
  • r798303142b
  • 2012年06月02日 10:47
  • 313

C#线程系列讲座(4):同步与死锁

转自:http://www.cnblogs.com/nokiaguy/archive/2008/07/25/1251756.html 虽然线程可以在一定程度上提高程序运行的效率,但也会产生一...
  • KAIFEIXIONGDI
  • KAIFEIXIONGDI
  • 2012年04月14日 15:45
  • 324

C#线程系列讲座(5):同步技术之Monitor

http://www.cnblogs.com/nokiaguy/archive/2008/07/31/1257625.html 在上一讲介绍了使用lock来实现线程之间的同步。实际上,这个lock是...
  • byondocean
  • byondocean
  • 2011年12月06日 21:18
  • 426

C#线程系列讲座(3):线程池和文件下载服务器

http://www.cnblogs.com/nokiaguy/archive/2008/07/16/1244746.html    如果设计一个服务器程序,每当处理用户请求时,都开始一个线程,将会...
  • byondocean
  • byondocean
  • 2011年12月06日 21:15
  • 441
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c#语言系列讲座(14) 结 构
举报原因:
原因补充:

(最多只允许输入30个字)