C#中的结构和类

对于 C/C++而言,结构和类的差别非常小,而在 C#中,很多时候,只是声明的时候关键字一个是 class,一个是 struct 而已。

以下定义一个结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public struct MyStruct
{
private string MyString;
private int MyNum;
public string MyString
{
get
{
return MyString;
}
set
{
MyString = value;
}
}
public int GetMyNum()
{
return MyNum;
}
}

可以看到结构体和类非常相似,但细纠起来,还是有很多的不同。

结构

  • 结构属于值类型,继承自 System.ValueType,值类型在堆栈上分配地址。值类型能够降低垃圾回收,表现出更好的性能。但其也有不好的一面,比如会涉及到装箱拆箱等操作,因此不适合处理逻辑复杂的对象。所有基类型都是结构类型,如 int 对应的是 System.int32 结构。
  • 对于值类型,编译器既不会生成默认构造函数。也不会调用默认构造函数。因此 C#不允许结构体有无参的默认构造函数。结构体的构造函数内必须初始化所有变量。
  • 结构体对象之间赋值是创建新的结构,结构体不能从另外的结构继承,本身也不能够被继承,虽然结构没有明确的用 sealed 声明,可是结构是隐式的 sealed。
  • 虽然结构不能被继承 可是结构能够继承接口,方法和类继承接口一样。

内部结构

  • 没有默认的构造函数,但是能够添加构造函数;
  • 没有析构函数;
  • 没有 abstract 和 sealed,不能有 protected 修饰符;
  • 可以不使用 new 实例化;
  • 在结构初始化实例字段是错误的。

  • 类是属于引用类型,继承自 System.Object,引用类型是在堆上面分配地址。类对象之间的赋值是通过复制引用实现的。

  • 如何不加 sealed 修饰符,类是可以继承其他类和接口且本身也可被继承。

内部结构

  • 有默认的构造函数;
  • 有析构函数;
  • 可以使用 abstract 和 sealed,有 protected 修饰符;
  • 必须使用 new 初始化。

使用

  • 堆栈的空间有限,对于有大量逻辑的复杂对象,使用类比结构体好一些。
  • 在表示抽象和多级别层次的对象时,使用类是更好的选择。
  • 在大多数情况下对象的类型只是数据时,使用结构是最好的选择。