关于结构

  类的对象存储在堆中,引用存储在栈里面,这样数据的生存期可以有很大的灵活性,但性能会有一定的损失。因为托管堆的优化,这种性能损失比较小。但是,有时候仅需要一个小的数据结构,此时类提供的功能多于我们需要的功能,出于性能考虑,我们最好用结构。看下面的代码:

    class Dimensions
    {
        public double Length;
        public double Width;
    }

  假如我们试着在计算机上布置家具,并存储每件家具的尺寸,表面看来使字段变为公共字段会违背编程原则,但关键是我们实际上并不需要类的全部功能。现在有两个数字,把其当作一对来处理比单个处理要方便一些。既不需要很多方法,也不需要从类中继承,也不希望.NET运行库在堆中遇到麻烦和性能问题,只需要存储两个double类型即可。为此可以将其定义为一个结构,如下:

 struct Dimensions
    {
        public double Length;
        public double Width;
    }

  为结构定义函数与类完全相同。下面定义了结构的构造函数和属性:

struct Dimensions
    {
        public double Length;
        public double Width;
        public Dimensions(double length, double width)
        {
            Length = length;
            Width = width;
        }
        public double Diagnal
        {
            get { return Math.Sqrt(Length * Length + Width * Width); }
        }
    }

  结构是值类型,其存储在栈中或存储为内联(如果是堆中一个对象的一部分),其生存周期与简单的数据类型一样。

  • 结构不支持继承。
  • 结构构造函数的工作方式有一些特别,编译器总会提供一个无参默认构造,其不允许替换。
  • 使用结构,可以指定字段如何在内存中布局。

  下面说明结构与类的区别:

1:结构是值类型

  虽然结构是值类型,但语法上可将其当做类来处理,如下面所示:

  Dimensions dim = new Dimensions();
  dim.Width = 3;
  dim.Length = 3;

  由于是值类型,所以new运算符与类的new工作方式不同。其并不分配堆中的内存,而是只调用相应的构造函数,将传给他的参数初始化所有字段。所以将上面代码改成下面的方式也是完全合法的:

   Dimensions dim;
   dim.Width = 3;
   dim.Length = 3;

  由于结构的变量声明是为整个结构在栈中分配空间,所以可以直接赋值。

  结构是会影响性能的值类型,根据其使用方式,这种影响可能是正面的,也可能是负面的。正面的影响是为结构分配内存时,速度快,以为它们将内联或保存在栈中。在结构超出作用域被删除时,速度也很快,不需要等待垃圾回收。负面影响是,将其作为参数来传递或将其赋予另一个结构时,其内容被复制,而类则是只复制引用,所以性能有所损失,这样根据结构的大小,性能损失不同。注意,结构主要用于小的数据结构。但当把结构作为参数传递给方法时,应将其作为ref参数传递,以避免性能损失——此时只传递了结构在内存中的地址。

2、结构和继承

  结构不是作为继承设计的。这意味着他不能从一个类中继承。但他最终派生于Object,所以他可以访问或重写object的方法。不能为结构提供其他基类,因为每个结构都派生于ValueType。

3、结构的构造函数

  其定义与类的相同,但不允许定义无参的构造函数。其原因隐藏在.NET运行库的实现方式中。在一些极罕见的情况中,.NET不能调用用户自己定义的无参构造函数,所以微软直接禁止结构内使用无参构造。

  默认结构的构造函数将数值字段都初始化为0,将引用类型初始化为null,且都是隐式的给出,即使提供了其他的带参构造函数也是如此。提供字段的初始值不能够绕过默认构造函数,如下面的代码就会产生编译错误:

struct Dimensions
    {
        public double Length=3;
        public double Width=3;
    }
原文地址:https://www.cnblogs.com/xuekai-to-sharp/p/3566237.html