剽窃别人的

澳门新葡新京,构造是行使 struct
关键字定义的,与类平日,都意味能够分包数据成员和函数成员的数据构造。
经常情状下,大家超级少使用布局,而且不菲人也并不提议使用布局,但作为.NET
Framework 平时型別系统中的叁个基本结构,依然有需要理解一下的。
布局的特色: 构造是意气风发种值类型,而且没有必要堆分配。 布局的实例化能够不选拔new 运算符。
在组织表明中,除非字段被声称为 const 或 static,不然不大概开始化。
结构类型永恒不是空泛的,何况始终是隐式密闭的,因而在布局注解中差异意行使abstract和sealed修饰符。
构造无法宣称默许构造函数(未有参数的布局函数卡塔 尔(阿拉伯语:قطر‎或析构函数,但能够声明带参数的布局函数。
布局得以兑现接口,但无法从另三个布局或类世袭,并且无法作为七个类的基,全数构造都间接接轨自System.ValueType,前者继续自
System.Object。 布局在赋值时开展复制。
将协会赋值给新变量时,将复制全体数据,并且对新别本所做的别样纠正不会变动原始别本的数量。
在选用值类型的会合(如 Dictionary<string,
myStruct>卡塔 尔(阿拉伯语:قطر‎时,请必需牢牢记住那或多或少。
布局类型的变量直接包罗了该组织的数额,而类品种的变量所富含的只是对相应数额的二个引用(被援用的数据称为“对象”卡塔尔国。不过布局还是可以够透过ref和out参数引用格局传送给函数成员。
结构可用作可以为 null 的档期的顺序,由此可向其赋 null 值。

  

struct A
{
public int x; //不能直接对其进行赋值
public int y;
public static string str = null; //静态变量可以初始化
public A(int x,int y) //带参数的构造函数
{
this.x = x;
this.y = y;
Console.WriteLine("x={0},y={1},str={2}", x, y,str);
}

}
class Program
{
static void Main(string[] args)
{
A a = new A(1,2);
A a1 = a;
a.x = 10;
Console.WriteLine("a1.x={0}",a1.x);
Console.Read();
}
}


结果为:x=1,y=2,str=            a1.x=1 此时a1.x值为1是因为,将a赋值给a1是对值进行复制,因此,a1不会受到a.x赋值得改变而改变。

但如果A是类,这时a和a1里的x引用的是同一个地址,则a1.x的值会输出10。

结构的装箱与拆箱

我们知道,一个类类型的值可以转换为 object 类型或由该类实现的接口类型,这只需在编译时把对应的引用当作另一个类型处理即可。 与此类似,一个object 类型的值或者接口类型的值也可以被转换回类类型而不必更改相应的引用。当然,在这种情况下,需要进行运行时类型检查。 由于结构不是引用类型,上述操作对结构类型是以不同的方式实现的。 当结构类型的值被转换为object 类型或由该结构实现的接口类型时,就会执行一次装箱操作。 反之,当 object 类型的值或接口类型的值被转换回结构类型时,会执行一次拆箱操作。 与对类类型进行的相同操作相比,主要区别在于: 装箱操作会把相关的结构值复制为已被装箱的实例,而拆箱则会从已被装箱的实例中复制出一个结构值。 因此,在装箱或拆箱操作后,对“箱”外的结构进行的更改不会影响已被装箱的结构。


struct Program
{
static void Main(string[] args)
{
int i = 1;
object o = i; //隐式装箱
i = 123;
Console.WriteLine("i={0},o={1}",i,o);
Console.Read();
}
}
//结果为:i=123,o=1

 结构与构造函数 

我们知道结构不能使用默认的构造函数,只能使用带参数的构造函数,当定义带参数的构造函数时,一定要完成结构所有字段的初始化,如果没有完成所有字段的初始化,编译时会发生错误­。 结构可以使用静态构造函数吗? 可以,结构的静态构造函数与类的静态构造函数所遵循的规则大体相同。 结构的静态构造函数何时将触发呢? 结构的实例成员被引用,结构的静态成员被引用,结构显示声明的构造函数被调用。 但是创建结构类型的默认值不会触发静态构造函数。为什么结构不能自定义无参数的构造函数? 结构类型的构造函数与类的构造函数类似,用来初始化结构的成员变量,但是struct不能包含显式默认构造函数, 因为编译器将自动提供一个构造函数,此构造函数将结构中的每个字段初始化为默认值表中显示的默认值。 然而,只有当结构用new实例化时,才会调用此默认构造函数。对值类型调用默认构造函数不是必需的。


struct A
{
static A()
{
Console.WriteLine("I am A.");
}
public void Fun()
{

}
}
class Program
{
static void Main(string[] args)
{
A a=new A();
a.Fun(); //结构的实例成员被引用
Console.Read();
}
}
结果为:I am A.


 结构与继承: 

一个结构声明可以指定实现的接口列表,但是不能指定基类。 由于结构不支持类与结构的继承,所以结构成员的声明可访问性不能是 protected 或 protected internal。 结构中的函数成员不能是 abstract 或 virtual,因而 override 修饰符只适用于重写从 System.ValueType 继承的方法。 为在设计编程语言时将结构设计成无继承性?­ 其实类的继承是有相当的成本的 ——由于继承性,每个类需要用额外的数据空间来存储“继承图”来表示类的传承历史, 通俗地说来就是我们人类的家族家谱,里面存储着我们的祖宗十八代,只有这样我们才知道我们从哪里来的,而家谱肯定是需要额外的空间来存放的。 大家不要觉得这个存放“继承图”的空间很小,如果我们的程序需要用10000个点(Point)来存放游戏中的人物形体数据的话, 在一个场景中又有N个人,这个内存开销可不是小数目了。所以我们可以通过将点(Point)申明成 Struct而不是class来节约内存空间。

interface ITest
{
void Fun(int x,int y);
}
struct A:ITest
{
public void Fun(int x,int y) //隐式实现接口里的方法
{
Console.WriteLine("x={0},y={1}", x, y);
}
}
class Program
{
static void Main(string[] args)
{
A a; //结构的实例化可以不使用new
a.Fun(1, 2);
Console.Read();
}
}
// 结果为:x=1,y=2


 什么情况下结构的实例化可以不使用new?

当结构中没有参数时,结构的实例化可以不使用new;

当结构中有参数时,必须对结构中所有参数进行初始化后,才能不使用new对结构进行实例化。

什么时候使用结构?

结构体适合一些小型数据结构,这些数据结构包含的数据以创建结构后不修改的数据为主;

例如:struct类型适于表示Point、Rectangle和Color等轻量对象。

尽管可以将一个点表示为类,但在某些情况下,使用结构更有效。

如果声明一个10000个Point对象组成的数组,为了引用每个对象,则需分配更多内存;这种情况下,使用结构可以节约资源。­

定义的时候不会用到面向对象的一些特性;

结构体在不发生装箱拆箱的情况下性能比类类型是高很多的.

  C#中组织类型和类项目在语法上太帅似,他们都以风流洒脱种数据布局,都能够包涵数据成员和办法成员。布局是意气风发种值类型,况兼无需堆分配。
布局的实例化能够不选拔 new 运算符。

  总体评价:

  在布局证明中,除非字段被声称为 const 或
static,不然不能够初阶化。
组织类型恒久不是空泛的,并且一向是隐式密闭的,由此在布局注明中不容许行使abstract和sealed修饰符。布局无法宣称私下认可布局函数(未有参数的结构函数卡塔 尔(阿拉伯语:قطر‎或析构函数,但足以注解带参数的构造函数。

  全体构造都直接接轨自System.ValueType,后面一个继续自 System.Object。
布局在赋值时实行理并答复制。将组织赋值给新变量时,将复制全数数据,而且对新别本所做的任何校勘不会改换原始别本的数量。 

  在选用值类型的集聚(如
Dictionary<string, myStruct>卡塔 尔(阿拉伯语:قطر‎时,请必需牢牢记住那或多或少。
布局类型的变量直接包涵了该组织的数额,而类项目标变量所包含的只是对相应数额的多个引用(被援引的数据称为“对象”卡塔 尔(英语:State of Qatar)。不过构造还能够透过ref和
out参数引用格局传送给函数成员。 布局可用作可感觉 null
的种类,由此可向其赋 null 值。

1、结交涉类的区分

  组织和类的分别:

  1、构造是值类型,它在栈中分配空间;而类是援引类型,它在堆中分配空间,栈中保存的只是引用。

  2、结构类型直接存款和储蓄成员数量,让别的类的多寡坐落于对中,坐落于栈中的变量保存的是指向堆中多少对象的援引。

  3、构造类型可以有实例布局函数和静态构造函数,但不可能有析构函数。

  C#中的轻巧类型,如int、double、bool等都以布局类型。如若必要的话,以至能够使用结构类型结合运算符运算重载,再为C#语言制造出生龙活虎种新的值类型来。

  

  和类的相比:

                        结构
                   类
  数据类型                值类型                  援用类型
  是或不是必需接收new运算符实例化      否                    是
  是或不是可注解无参数的布局函数       否                    是
  数据成员是还是不是在注明的同有时候起先化     证明为const或static能够,数据成员不得以 
能够
  直接派生自什么项目           System.ValueType           
 有
  是不是有析构函数             无                    有
  可不可以从类派生              否                    能够
  可否达成接口              能够                   能够
  实例化时在栈照旧在堆分配内部存储器      栈                    堆,栈中保存援引
  该类型的变量可以还是不可以被赋值为null      
否                    能够
  可不可以定义私有的无参构造函数       否                    能够
  是还是不是总有八个私下认可的无参布局函数      
是                    否

  不论构造选用预约义的、无参数的布局函数,还是采纳顾客定义的、有参数的结构函数举行开端化,都会开端化构造的数码成员。然而预订义的,无参的
会将数值型初叶化为默许值,援引类型开首化为null;而顾客自定义的初叶化战术对个成员实行最早化。因而构造类型的数据成员不允许在宣称是显式开头化。

 

  由于组织是值类型,而且直接存款和储蓄数据,因而在一个目的的珍视成员为多少且数据量十分的小的动静下,使用构造会拉动更加好的性质。当为布局分配内部存储器,可能当协会超过了功效域被删除时,品质会十分好,因为她们将内联大概保存在仓库中。当把多少个组织类型
的变量赋值给另二个构造时,对质量的震慑决意于布局的高低,固然组织的数额成员特别多况且复杂,就能够促成损失。

 

  结谈判类的适用项合分析:

  1、当货仓的空中很有限,且有恢宏的逻辑对象时,创设类要比成立布局好有的;

  2、对于点、矩形和颜色那样的轻量对象,假诺要评释一(Wissu卡塔尔国个分包许四个颜色对象的数组,则CLRAV4供给为各类对象分配内部存款和储蓄器,在此种情形下,使用布局的资金好低;

  3、在表现抽象和多级其他对象档期的顺序时,类是最棒的选用,因为布局不帮忙世襲。

  4、大多数景观下,目的项目只是包含一些数额,恐怕以数量为主。

 

struct A
{
public int x; //不能直接对其进行赋值
public int y;
public static string str = null; //静态变量可以初始化
public A(int x,int y) //带参数的构造函数
{
this.x = x;
this.y = y;
Console.WriteLine("x={0},y={1},str={2}", x, y,str);
}

}
class Program
{
static void Main(string[] args)
{
A a = new A(1,2);
A a1 = a;
a.x = 10;
Console.WriteLine("a1.x={0}",a1.x);
Console.Read();
}
}

 

二、布局体的定义与赋值

2.1 架构体的表明

    public struct AddressBook
    { 
        //字段、属性、方法、事件
    }

  对于类来说,三个变量指向同叁个指标的情形是存在的,由此对如此三个变量中的自便四人展览开操作,起结果一定会耳熟能详其它三个,因为它们照准的是同叁个指标。

  构造体是值类型,直接包蕴它和煦的数额,每种组织都封存本身的生龙活虎份数据,校勘每多少个结构的多寡都不会对别的组织的数据变成影响。

  假如从协会中开创三个对象,并将该指标赋给有个别变量,则该变量包涵布局的全体值。复制类型为构造的变量时,将同期复制该组织所具备的装有数据。由于组织不是援引类型,因而构造类型的变量无法被付与null值。

 

澳门新葡新京 1澳门新葡新京 2

public class Program
    {
        static void Main(string[] args)
        {
            PersonStruct p1, p2;    //与类一样,但可以不new
            p1.Name = "张飞";
            p1.MobilePhone = "13553663108";
            p1.Birthday = DateTime.Now.AddYears(-10);

            p2 = p1;              //将p1的值赋给p2   //由于是值类型,因此赋值等于将全部值全部复制到p2的栈空间
            p2.Name = "关羽";     //然后修改p2的值看是否会影响p1
            Console.WriteLine(p1.Name);     //输出 张飞 没影响

            PersonClass p3 = new PersonClass();    
            p3.Name = "张飞";
            p3.MobilePhone = "13553663108";
            p3.Birthday = DateTime.Now.AddYears(-10);

            PersonClass p4 = new PersonClass();
            p4 = p3;              //将p3的值赋给p4   赋值后,由于是引用类型,因此两个对象指向的是同一个地址(堆空间)
            p4.Name = "关羽";     //然后修改p4的值看是否会影响p3
            Console.WriteLine(p3.Name);     //输出 关羽 有影响

            Console.ReadKey();
        }
    }

    public class PersonClass
    {
        public string Name;
        public string MobilePhone;
        public DateTime Birthday;
    }

    public struct PersonStruct
    {
        public string Name;
        public string MobilePhone;
        public DateTime Birthday;
    }

View Code

 

  将多个布局变量赋值给另多个协会变量,正是把多少从贰个布局复制到另一个布局。而类则不一样,在类的变量之间,复制的是援用,并非类数据。。因而当数码超大的时候,这种数据复制机制会拉动比较大的支付

2.2 实例布局函数

  结构类型都有五个预订义的,未有参数的布局函数,那一点与类是雷同的。此布局函数不容许删除和重定义,并且这一个无参数的布局函数会平昔留存,并不会因为定义了别的带参数的结构函数就排除,那或多或少和类不一致。

   只顾若无使用new运算符,是不得以应用数据成员的值(除非已呈现地安装了该多少成员的值)和调用函数成员的(除非所有数据成员均已经被赋值)。

struct A
{
static A()
{
Console.WriteLine("I am A.");
}
public void Fun()
{

}
}
class Program
{
static void Main(string[] args)
{
A a=new A();
a.Fun(); //结构的实例成员被引用
Console.Read();
}
}
结果为:I am A.

  布局无法运用默许的布局函数,只好使用带参数的构造函数,当定义带参数的构造函数时,一定要变成结构有所字段的最初化,若无实现全体字段的初叶化,编写翻译时会爆发错误­。
布局得以接收静态构造函数吗?
可以,布局的静态架构函数与类的静态布局函数所固守的法则大致相仿。
布局的静态结构函数何时将触发呢?
布局的实例成员被援用,构造的静态成员被引述,布局突显表明的构造函数被调用。
可是开创结构类型的暗中同意值不会接触静态布局函数。为何构造不可能自定义无参数的构造函数?
构造类型的布局函数与类的结构函数相同,用来发轫化布局的分子变量,但是struct不可能饱含显式默许布局函数,
因为编译器将活动提供二个结构函数,此构造函数将组织中的每一种字段初步化为私下认可值表中显得的默许值。
然则,独有当组织用new实例化时,才会调用此暗中同意布局函数。对值类型调用暗许布局函数不是必得的。

2.3 静态构造函数

  和类同样,布局类型也得以有静态布局函数,静态构造函数用于开头化静态数据成员。静态构造函数犹如下特点:

  1、静态布局函数无法有访谈修饰符和参数;

  2、静态布局函数不可能访谈实例成员;

  3、静态构造函数不可能直接实行调用;

  结议和类的静态布局函数的触发法则差别,类的静态构造函数是在创制第贰个实例或引用任张伟刚态成员从前自动调用的,而布局的静态布局函数在以下景况调用:

  1、使用显式声明的结构函数实行初阶化

  2、调用构造的艺术或访问布局的静态数码成员(无论是读取依然赋值,访问实例数据成员不会触发CL奥迪Q5自动调用静态的构造函数)。

 

3、布局的多态和可世襲性

  构造向来派生自System.ValueType,直接派生自System.Object,但构造是隐式密闭的,不可能看做基类在派生出别的的协会,也无法从类派生,但足以从接口派生。

  构造的特色:

  1、布局类型总是隐式密封的,因而在概念构造时不可能使用sealed和abstract关键字;

  2、因为布局无法看做基类,布局的成员不可能动用如下访谈修饰符:protected和protected,internal;

  3、结构的函数成员不能够声称为abstract和virtual,但是足以应用override关键字,用以覆写它的基类System.ValueType中的方法。

 

interface ITest
{
void Fun(int x,int y);
}
struct A:ITest
{
public void Fun(int x,int y) //隐式实现接口里的方法
{
Console.WriteLine("x={0},y={1}", x, y);
}
}
class Program
{
static void Main(string[] args)
{
A a; //结构的实例化可以不使用new
a.Fun(1, 2);
Console.Read();
}
}
// 结果为:x=1,y=2

 二个构造注明能够钦命达成的接口列表,不过不能够钦点基类。
由于组织不帮衬类与构造的存在延续,所以协会成员的宣示可访问性不可能是 protected 或 protected internal。
结构中的函数成员不能够是 abstract 或 virtual,因此 override 修饰符只适用于重写从 System.ValueType 继 承的章程。
为在统筹编制程序语言时将布局划虚构计成无世襲性?­ 其实类的持续是有一定的财力的
——由于世襲性,每一个类须求用额外的多少空间来囤积“继承图”来代表类的负责历史,
通俗地说来就是我们人类的家门家谱,里面积攒着大家的祖辈十五代,只有这么我们才知道大家从哪个地方来的,而家谱鲜明是亟需非凡的长空来存放在的。
我们不要认为那一个寄存“世襲图”的半空中极小,假若大家的顺序须要用10000个点(Point)来存放游戏中的人物形体数据以来,
在二个场景中又有N个人,那些内部存储器花费可不是小数目了。所以大家得以因此将点(Point)注解成
Struct实际不是class来节本省部存款和储蓄器空间。

 

4、布局的装箱与拆箱

  组织是值类型,由此当它被改造为object类型时,或许它所完毕的接口类型的时候,就能施行李装运箱操作;同样,当施行相反操作的时候,就能够实践拆箱操作。

  叁个类类型的值能够转变为 object 类型或因此类完成的接口类型,那只需在编写翻译时把相应的援引当做另贰个品类管理就可以。
与此相同,一个object 类型的值或许接口类型的值也足以被更改回类类型而毋庸修改相应的援用。当然,在这里种气象下,供给开展运作时类型检查。
是因为组织不是援用类型,上述操作对构造类型是以分裂的法子落到实处的。
当组织类型的值被撤换为object 类型或由该组织完结的接口类型时,就能够实行一遍装箱操作。
反之,当 object 类型的值或接口类型的值被转变回构造类型时,会试行三次拆箱操作。

  与对类类型举行的平等操作相比较,首要差距在于:
装箱操作会把有关的布局值复制为已棉被服装箱的实例,而拆箱则会从已棉被服装箱的实例中复制出二个布局值。
由此,在装箱或拆箱操作后,对“箱”外的布局举办的更改不会潜濡默化已被装箱的协会。

struct Program
{
static void Main(string[] args)
{
int i = 1;
object o = i; //隐式装箱
i = 123;
Console.WriteLine("i={0},o={1}",i,o);
Console.Read();
}
}
//结果为:i=123,o=1

 

 

 

参照他事他说加以考查文章

1. 逆心. C# 结构体
struct,
2013-5.

2. kuangkro.
C#之结构struct(转), 2013-3.

 

 

 

相关文章