结构是使用 struct 关键字定义的,与类相似,都表示可以包含数据成员和函数成员的数据结构。 一般情况下,我们很少使用结构,而且很多人也并不建议使用结构,但作为.NET Framework 一般型別系统中的一个基本架构,还是有必要了解一下的。

结构的特征: 结构是一种值类型,并且不需要堆分配。 结构的实例化可以不使用 new 运算符。

在结构声明中,除非字段被声明为 const 或 static,否则无法初始化。 结构类型永远不是抽象的,并且始终是隐式密封的,因此在结构声明中不允许使用abstract和sealed修饰符。

结构不能声明默认构造函数(没有参数的构造函数)或析构函数,但可以声明带参数的构造函数。 结构可以实现接口,但不能从另一个结构或类继承,而且不能作为一个类的基,所有结构都直接继承自System.ValueType,后者继承自 System.Object。 结构在赋值时进行复制。 将结构赋值给新变量时,将复制所有数据,并且对新副本所做的任何修改不会更改原始副本的数据。 在使用值类型的集合(如 Dictionary

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

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

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

struct结构体(剽窃别人的)的更多相关文章

  1. C# Struct结构体里数组长度的指定

    typedef struct Point{ unsigned short x; unsigned short y; }mPoint;//点坐标 typedef struct Line{ mPoint ...

  2. C#基础--struct(结构体)

    结构体和类有点类似    我们定义一个类的时候    是class   类名   定义结构体的时候是 struct   结构体名 结构体的写法 struct Point { // public int ...

  3. 1.0 基础、标示符、常量、数据类型(enum 枚举,struct 结构体)、操作符、循环、数组

    一.程序 现实生活中,程序是指完成某些事务的一种既定方法和过程,可以把程序看成是一系列动作执行过程的描述. 在计算机世界,程序是指令,即为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集 ...

  4. C#语言struct结构体适用场景和注意事项

    在C#语言中struct结构体和class之间的区别主要是值类型和引用类型的区别,但实际上如果使用不当是非常要命的.从Win32时代过来的人对于struct一点不感觉陌生,但是却反而忽略了一些基本问题 ...

  5. C语言 Struct 结构体在 Java 中的体现

    大一整个学期完成了 C 语言的学习,大二就进入了Java 的学习. 和C语言一样,我们都会尝试写一个小小的学生管理系统什么的,学习过 C 语言同学知道,在管理系统中 Struct 结构体是个很好用的东 ...

  6. Swift Struct 结构体

    前言 Swift 语言有两种基本的数据类型,即类(class)和结构体(struct),class 这样的概念大家不会陌生,而 struct 也并不是什么新的概念,在 Objective-C 和 C ...

  7. go struct结构体

    struct结构体 用来自定义复杂数据结构 struct里面可以包含多个字段(属性),字段可以是任意类型 struct类型可以定义方法,注意和函数的区分 struct类型是值类型 struct类型可以 ...

  8. struct 结构体解析(原)

    (一)基本概念 结构体是一个或是多个变量的集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组合在一个名字之下.我们将关键字struct引入了结构声明中.结构声明包含在花括号内的一系列声明组成 ...

  9. struct结构体在c和c++中的差别

    非常多次遇到这个struct的问题,今天在这里简单总结一下我的理解 一.struct在C 中的使用 1.单独使用struct定义结构体类型 struct Student { int id; int n ...

  10. Go - Struct 结构体

    目录 概述 声明结构体 生成 JSON 改变数据 推荐阅读 概述 结构体是将零个或多个任意类型的变量,组合在一起的聚合数据类型,也可以看做是数据的集合. 声明结构体 //demo_11.go pack ...

随机推荐

  1. [osx] 查看端口被占用

    netstat命令 netstat -an | grep 3306 3306替换成需要grep的端口号 lsof命令 sudo lsof -i :80 -i参数表示网络链接,:80指明端口号,该命令会 ...

  2. The constructor BASE64Encoder() is not accessible due to restriction on required library

    在Eclipse中编写Java代码时,用到了BASE64Decoder,import sun.misc.BASE64Decoder;可是Eclipse提示:Access restriction : T ...

  3. World Wind .NET源码编译问题处理

    World  Wind  .NET源码编译问题处理 下载了World_Wind_1.4.0_Source源码(http://worldwindcentral.com/wiki/NASA_World_W ...

  4. 【笔记】css hover 伪类控制其他元素

    最近在模仿一个网站的项目 当中有一个效果需要利用到hover效果因为不太想写jq脚本所以百度了一下css hover的运用发现原来hover也可以控制其他元素的变化的 但是这有一个要求 就是添加hov ...

  5. 零成本实现Web性能测试:基于Apache JMeter

    http://book.51cto.com/art/201204/327301.htm

  6. 突袭HTML5之WebGL 3D概述

    WebGL开启了网页3D渲染的新时代,它允许在canvas中直接渲染3D的内容,而不借助任何插件.WebGL同canvas 2D的API一样,都是通过脚本操纵对象,所以步骤也是基本相似:准备工作上下文 ...

  7. U-Boot移植

    基于天翔的老师的课程, 他的博客在这儿: http://blog.csdn.net/johnmcu/article/details/6561311 注明不能转载, 就重新写一下吧: 1. 安装韦东山的 ...

  8. phpcms v9调用自定义字段的方法步骤

    代码如下:{loop $shigongtu $r}<img src="{$r[url]} " title="测试"/>{/loop} 2 首页,分页 ...

  9. Mysql索引的类型和优缺点

    索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.注:[1]索引不是万能的!索引可以加快数据检索操作,但会使数据修改操作变慢.每修改数据 ...

  10. zigbee学习之路(十二):zigbee协议原理介绍

    一.前言 从今天开始,我们要正式开始进行zigbee相关的通信实验了,我所使用的协议栈是ZStack 是TI ZStack-CC2530-2.3.0-1.4.0版本,大家也可以从TI的官网上直接下载T ...