一、什么是结构
- 含义:
- 结构是程序员定义的数据类型,与类十分相似。结构中可包含数据成员和函数成员。
- 结构使用struct关键字。
- 结构声明:
struct StructName
{
//Members...
}
二、结构的特点
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可以定义构造函数,但不能定义析构函数(析构函数与构造函数作用相反)
- 结构是指类型
- 结构是隐式密封的,因此不支持继承。
- protected、internal、abstract、virtual不能用于结构
- 可以实现接口
三、结构和类的区别
比较 | 结构 | 类 |
声明 | 使用struct关键字 | 使用class关键字 |
类型 | 值类型 | 引用类型 |
继承 | 隐式密封类,不支持 | 支持 |
析构函数 | 不能有 | 可以有 |
无参构造 | 隐式的预定义的无参构造,不能删除和重定义 | 在没有其他构造函数声明时隐式提供无参构造,无参构造可以重定义 |
字段初始化 | 不允许(必须显式声明有参构造才允许初始化) | 允许 |
成员修饰符 | protected,internal,abstract和virual不可用 | 都可以使用 |
类型变量 | 不可以为null | 可以为null |
四、对结构赋值
把一个结构赋值给另一个结构,就将一个结构的值赋值给另一个结构。
//结构
struct Simple
{
public int X;
public int Y;
}
//类
class CSimple
{
public int X;
public int Y;
}
//测试
class Program
{
static void Main(string[] args)
{
CSimple cs1 = new CSimple(), cs2 = null;//类实例
Simple ss1 = new Simple(), ss2 = new Simple();//结构实例,结构实例不能被赋值为null,因为是值类型,null是引用类型默认值
cs1.X = ss1.X = 5;//将5赋值给ss1.X和cs1.X
cs1.Y = ss1.Y = 10;//将10赋值给ss1.Y和cs1.Y
cs2 = cs1;//赋值类实例
ss2 = ss1;//赋值结构实例
Console.WriteLine("cs1.X = {0},cs1.Y = {1}",cs1.X,cs2.Y);
Console.WriteLine("ss1.X = {0},ss1.Y = {1}",ss1.X,ss2.Y);
Console.WriteLine("cs2.X = {0},cs2.Y = {1}",cs2.X,cs2.Y);
Console.WriteLine("ss2.X = {0},ss2.Y = {1}",ss2.X,ss2.Y);
}
}
代码图解:
五、结构实例构造函数
在类与结构中的对比中提及无参构造和初始化成员。现在来进行说明。
1. 结构中的无参构造
- C#为隐式地为每个结构提供一个无参构造,这个构造把结构的每个成员设置为该成员类型的默认值。(值成员为各自类型的默认值,引用成员为null)
- C#提供的无参构造不能显式声明,也就说不能被重新自定义这个无参构造,只能在构造函数中声明有参构造。
2.结构成员初始化
- 当结构中没有有参构造时,结构成员的表达式不能在结构中初始化。
- 当结构中包含了有参构造,结构成员可以在结构中初始化。
3.new结构和不new结构
- 结构即使不从堆中分配内存,也要使用new关键字创建结构实例
- 当不使用new关键字创建结构实例时可以直接使用结构中的数据成员,但有一些限制:
- 在显示设置数据成员后,才能使用它们的值
- 在对所有数据成员赋值后才能调用函数成员
//结构
struct Simple
{
public int X;
public int Y;
public void PrintOut()
{
Console.WriteLine("在对结构中的所有数据成员赋值后才能调用结构中的函数成员");
}
}
//测试
class Program
{
static void Main(string[] args)
{
Simple simple;
simple.X = 10;
//simple.PrintOut();//没有对结构中的所有数据成员赋值就调用了结构中的函数成员,编译器报错:使用了未赋值的局部变量simple
simple.Y = 100;
simple.PrintOut();
}
}