C#中的结构

结构

问题一:什么是结构?

结构(struct)是自定义的一种数据类型,与类(class)很相似,具有数据成员和函数成员。 结构与类的区别是:

  • 是引用类型,结构是值类型;
  • 结构是隐式的、密封的,因此不能像类那样被派生。

声明结构的语法与声明类相似:

1
2
3
4
struct StructName
{
MemberDeclarations
}

值类型的结构

既然是值类型,那么结构变量就含有自己的数据,因此:

  • 结构类型的变量不能为null;
  • 两个结构变量不能引用同一对象。

对比结构和类的代码: 类的声明:

1
2
3
4
5
class DemoClass
{
public int x;
public int y;
 }

结构的声明:

1
2
3
4
5
struct DemoStruct
{
public x;
public y;
}

给结构赋值

class2 = class1;

上面这个给类赋值的语句,只是复制了数值的引用,即这样赋值以后,class1和class2这两个引用,都是指向堆中的相同对象。而像下面这样给结构赋值的话:

struct2 = struct1;

struct1的数值会直接复制到struct2中,此时在栈中存在struct1和struct2两个内容相同但各自完全独立的对象。

结构类型的构造函数

结构,可以有实例构造函数,也可以有静态构造函数,但是不允许有析构函数。

实例构造函数

编译器会隐式的提供一个默认构造函数,将结构中的每个成员设为该类型的默认值。 与类不同,如果手动为类创建构造函数,那么隐式的无参数构造函数就无效了。但是结构的默认构造函数不能删除或重定义,即使手动编写结构的构造函数,默认的无参数构造函数仍然有效。 实例化结构与类一样,要用new语法,例如:

1
2
3
4
5
6
7
8
9
10
11
12
struct DemoStruct
{
    whatever inside;
}
class Program
{
    static void Main()
    {
        DemoStruct s1 = new DemoStruct(); //隐式构造函数
        DemoStruct s2 = new DemoStruct( 5, 10 ); //自定义构造函数
    }
}

静态构造函数

结构类型的静态构造函数与类是相同的,静态构造函数创建并初始化静态数据成员,不能引用实例成员。

在结构中不允许使用字段初始化语句

例如,下面的语句不能编译通过:

1
2
3
4
struct Simple
{
    public int = 10;  //这是不可以的!
}

密封

结构是密封的,不允许派生,不支持继承,不能使用以下修饰符:

protected
internal
abstract
virtual

结构是派生自System.ValueType,而System.ValueType派生自Object。 可以用于结构成员并与继承相关的关键字是new和override,当创建于结构的基类System.ValueType的成员相同名称的成员时可以使用这两个修饰符。

装箱和拆箱

与其它值类型一样,如果要将结构实例作为引用类型的对象,就必须进行装箱。

结构作为返回值和参数

  • 当结构作为返回值时,将创建一个副本,从函数成员返回。
  • 当结构作为值参数时,也是创建一个副本,用于方法执行中。
  • 把结构作为ref或out参数的话,传入方法的是结构的一个引用,方法可以修改原结构数据成员。

关于结构的其它注意事项

如果不打算包含方法,那么可以用结构代替类,因为结构的实例开销比较小。但是要注意装箱和拆箱的代价更大,所以如果需要引用类型,也许还是应该考虑使用类。

预定义的简单类型,如intshortlong等等,尽管在.Net和C#中被视为原始类型,但其实他们在.Net中都实现为结构。 可以声明分部结构(使用partial关键字),这与类是相同的。 与类一样,可以实现接口

留言