在C#中,数据类型有两种:值类型和引用类型()。在值类型中,struct是非常重要的一个类型,可以说struct是一个真正的值类型,因为struct是从System.ValueType继承的,并且System.ValueType还是一个抽象类,不属于值类型,同时简单类型,枚举等本质上都是一个struct。

现在就说说struct。struct既然是个值类型,自然应该在线程堆栈上。对于struct,在一定程度上与class非常相像,接下来,我们来分析一下。

class program
    {
        static void Main(string[] args)
        {
            STR str1;
            str1.Method("str1");//第一种方法,直接定义
 
            STR str2 = new STR();
            str2.Method("str2"); //第二种方法,通过new关键字
        } 
    }
    struct STR
    {
        public void Method(string Par)
        {
参数是:"+Par);
        }
}

我们看到,结构中,我们可能有两种方法来调用结构内部的成员,一个是直接定义来调用,也可以通过new关键字来定义调用,这是与类不同的,类必需经过实例化(new)来定义调用(静态成员是通过类名调用,没有定义)。

接下来再看一个例子。

class program
    {
        static void Main(string[] args)
        {
            STR str1;//第一种

赋值

Console.WriteLine(str1.count);
 
            STR str2 = new STR();//第二种
            Console.WriteLine(str2.count); 
                   
        } 
    }
    struct STR
    {
      public int count;
}

当结构体中定义一个全局变量时(类中叫字段),这个count是没有值的,这是与类不同的,在类中,所有的字段都有默认值,结构中是没有的。既然没有默认值,那在第二种实例化直接调用时,str2.count输出的为什么是0,这个0是没有事前赋值的。如果是类,我们知道,类是有构造函数的,如果我们不显式写上构造函数,CLR会自动给我们加上一个没有参数的构造函数的,并且这个构造函数是可以被显式的写出来的。同样,结构也是有一个构造函数,但这个构造函数是不能够写出来的,并且这个构造函数很特别,我们从第二种就能看出,只要用new关键字来实例化结构,就会把count给初始化成0,也就是那个不能写出来的无参构造函数会初始化所有的结构中的全局变量。对于第一种,因为没有调用无参的构造函数,所以必需去显式的给结构中的全局变量去赋值。

如果结构里有有参构造函数,代码如下:

{
        static void Main(string[] args)
        {
            STR str = new STR("");//实例化
            Console.WriteLine(str.count);
        } 
    }
    struct STR
    {
      public int count;
      public STR(string str)
      {
          count = 1;
      }
 }

会发现,如果是个有参构造函数,在构造中必需去初始化结构中的全局变量,因为如果用有参构造函数的话,无参的就不会得到调用,结构中的全局变量就得不到初始化,所以必需在有参构造函数中去初始化它。如果有多个全局变量,都得在这个有参构造函数中去实例化它们。

综合上面,可以看出,结构可以用new来实例化,也可以不用new来实例化,如果用new,就必需,必需初始化结构里的全部局部变量,在这里,无参的构造构函是不需要写出来的,自动实现全局变量的初始化。