struct结构体(剽窃别人的)

结构是使用 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对象组成的数组,为了引用每一个对象,则需分配更多内存;这种状况下,使用结构能够节约资源。­

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

结构体在不发生装箱拆箱的状况下性能比类类型是高不少的.
相关文章
相关标签/搜索