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();
    }
}

image-20221028155936837

对结构赋值

把一个结构赋值给另一个结构,就是将一个结构的值复制给另一个结构。这和复制类变量不同,复制类变量只是复制引用 ❥

下面案例解释:

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();
    }
}

image-20221028163511281

构造函数和析构函数

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

实例构造函数 ❥

语言隐示的为每一个结构提供一个无参的构造函数,这 个构造函数把结构的每个成员设置为该类型的默认值,值成员设置他们的默认值,引用成员设置成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;
        // 赋值后就没有问题了
    }
}

静态构造函数

初始化静态数据成员

以下两种行为,任意一种发生之前,将会调用静态构造函数❥

  • 调用显示声明的构造函数
  • 引用结构的静态成员

构造函数和析构函数的总结 ❥

image-20221029003038726

字段初始化是不允许的 ❥

❥ 在结构中字段初始化语句是不允许的

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参数,传入方法的是该结构的一个引用,这样就可以修改其数据成员了。

关于结构的其他信息

image-20221029004713296

posted @ 2022-10-29 00:47  LD_Dragon_sky  阅读(73)  评论(0编辑  收藏  举报