8 结构
什么是结构
结构是程序定义的数据类型,与类非常相似,他们有数据成员和函数成员。 虽然与类相似,但是有许多重要的区别。
最重要的区别是:
- 类是引用类型 而结构是值类型
- 结构是隐示密封的,这意味着不能被派生
声明结构的语法与声明类相似
struct SturctName
{
...
}
例如声明Point的结构 ,他有两个字段 X Y
struct Point
{
public int X;
public int Y;
}
static void Main()
{
Point first,second,third;
first.X = 10;first.Y = 10;
...
}
结构是值类型
和所有的值类型一样,结构类型变量含有自己的数据。因此:
- 结构类型的变量不能为null;
- 两个结构变量不能引用同一对象
class CSimple
{
public int x;
public int y;
}
struct Simple
{
public int x;
public int y;
}
class Program
{
static void Main()
{
CSimple cs = new CSimple();
Simple ss = new Simple();
}
}
对结构赋值
把一个结构赋值给另一个结构,就是将一个结构的值复制给另一个结构。这和复制类变量不同,复制类变量只是复制引用 ❥
下面案例解释:
class Csimple
{ public int x;public int y; }
struct Ssimple
{ public int x;public int y; }
internal class Program
{
static void Main(string[] args)
{
Csimple cs1 = new Csimple(),cs2 = null;
Ssimple ss1 = new Ssimple(),ss2 = new Ssimple();
cs1.x = ss1.x = 10;
cs1.y = ss1.y = 15;
cs2 = cs1;
cs1.x = 100;
Console.WriteLine(cs2.x); // 100
ss2 = ss1;
ss1.x = 150;
Console.WriteLine(ss2.x); // 10
Console.ReadKey();
}
}
构造函数和析构函数
结构可以有实例构造函数和静态构造函数,但是不允许有析构函数。❥
实例构造函数 ❥
语言隐示的为每一个结构提供一个无参的构造函数,这 个构造函数把结构的每个成员设置为该类型的默认值,值成员设置他们的默认值,引用成员设置成null
和类不同,对于类,编译器只在没有其他构造函数声明时提供隐示的无参构造函数。
- 调用一个构造函数,需要使用new运算符,即使不从堆中分配内存也要使用new运算符。❥
/*
下面的代码声明了一个简单的结构,他有一个带int参数的构造函数
*/
struct Simple
{
public int x;
public int y;
public Simple(int a ,int b)
{
x = a;
y = b;
}
}
class Program
{
// 调用隐示构造函数
Simple s1 = new Simple();
// 调用构造函数
Simple s2 = new Simple(4,8);
}
也可以不使用new运算符创建结构的实例,然而,如果这样做,有一些限制。如下:
- 在显示设置数据成员之后,才能使用他们的值
- 在堆所有数据成员赋值之后,才能调用任何函数成员
struct Simple
{
public int x;
public int y;
}
class Program
{
static void Main()
{
Simple s1,s2; // 没有构造函数的调用!!!
// 现在使用会出现问题
s2.x = 10;
s2.y = 15;
// 赋值后就没有问题了
}
}
静态构造函数
初始化静态数据成员
以下两种行为,任意一种发生之前,将会调用静态构造函数❥
- 调用显示声明的构造函数
- 引用结构的静态成员
构造函数和析构函数的总结 ❥
❥
字段初始化是不允许的 ❥
❥ 在结构中字段初始化语句是不允许的
struct Point
{
public int x = 0; // 编译错误
}
结构是密封的
结构是密封的,因此无法派生其他结构
因为无法派生 所以有些访问修饰符就没有意义了 例如
- protected
- internal
- abstract
- virtual
结构本身派生自 System.ValueType
, System.ValueType
派生自object
两个可以用于结构成员并继承相关的关键字是new
override
修饰符,当创建一个和基类System.ValueType
的成员有相同名称的成员时使用他们 。所有结构都派生自System.ValueType
装箱和拆箱
如同其他值类型数据,如果想将一个结构实例作为引用类型对象,必须创建装箱的副本,装箱的过程就是制作值类型变量的引用类型副本
装箱和拆箱在后面讲解
结构作为返回值和参数
结构可以作为返回值和参数
- 返回值 当结构作为返回值时,将创建他的副本并从函数成员返回。
- 值参数 当结构被用作参数时,将创建实参结构副本。该副本用于方法的执行中。
- ref 和 out 参数 如果把一个结构用于ref或out参数,传入方法的是该结构的一个引用,这样就可以修改其数据成员了。
关于结构的其他信息
吾虽浪迹,却未迷失本心