C#图解教程 第十章 结构
结构
什么是结构
结构是程序员定义的数据类型,与类非常相似。它们有数据成员和函数成员。结构与类的重要区别是:
- 类是引用类型而结构是值类型
- 结构是隐式密封的,这意味着它们不能被派生
声明结构的语法与声明类相似
关键字
↓
struct SturctName
{
MemberDeclarations
}
例:Point结构
struct Point
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
Point first,second,third;
first.X=;first.Y=;
second.X=;second.Y=;
third.X=first.X+second.X;
third.Y=first.Y+second.Y;
Console.WriteLine("first: {0},{1}",first.X,first.Y);
Console.WriteLine("second: {0},{1}",second.X,second.Y);
Console.WriteLine("third: {0},{1}",third.X,third.Y);
}
}

结构是值类型
和所有值类型一样,结构类型变量含有自己的数据。因此:
- 结构类型变量不能为null
- 两个结构变量不能引用同一对象
例:结构变量的内存安排
class CSimple
{
public int X;
public int Y;
}
struct Simple
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
var cs=new CSimple();
var ss=new Simple();
...
}
}

对结构赋值
把一个结构赋值给另一个结构,就将一个结构的值复制给另一个结构。这和复制类变量不同,复制类变量时只复制引用。
例:结构变量赋值与类变量赋值的区别
class CSimple
{
public int X;
public int Y;
}
struct Simple
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
CSimple cs1=new CSimple(),cs2=null;
Simple ss1=new Simple(),ss2=new Simple();
cs1.X=ss1.X=;
cs1.Y=ss1.Y=;
cs2=cs1;
ss2=ss1;
}
}

构造函数和析构函数
结构可以有实例构造函数和静态构造函数,但不允许有析构函数。
实例构造函数
语言隐式地为每个结构提供一个无参构造函数。这个构造函数把结构的每个成员设置为该类型的默认值。值成员设置成它们的默认值,引用成员设置为null。
例:带参数的构造函数
struct Simple
{
public int X;
public int Y;
public Simple(int a,int b)
{
X=a;
Y=b;
}
}
class Program
{
static void Main()
{
var s1=new Simple();
var s2=new Simple(,);
Console.WriteLine("{0},{1}",s1.X,s1.Y);
Console.WriteLine("{0},{1}",s2.X,s2.Y);
}
}
也可以不是用new运算符创建结构实例,然而这样做,有一些限制:
- 在显式设置数据成员后,才能使用它们的值
- 在对所有数据成员赋值后,才能调用任何函数成员
例:不用new创建结构实例
struct Simple
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
Simple s1,s2;
Console.WriteLine("{0},{1}",s1.X,s1.Y); //编译错误
↑ ↑
还未赋值
s2.X=;
s2.Y=;
Console.WriteLine("{0},{1}",s2.X,s2.Y); //没错误
}
}
静态构造函数
与类相似,结构的静态构造函数创建并初始化静态数据成员,而且不能引用实例成员。
以下两种行为发生前,会调用静态构造函数
- 调用显式声明的构造函数
- 引用结构的静态成员
构造函数和析构函数小结

字段初始化语句是不允许的
在结构中字段初始化语句是不允许的。
struct Simple
{
public int x=; //编译错误
public int y=; //编译错误
}
结构是密封的
结构总是隐式密封的,因此,不能从它们派生其他结构。
结构不支持继承,所以下列修饰符不能用于结构声明:
- protected
- internal
- abstract
- virtual
结构都派生自System.ValueType,System.ValueType派生自object。
两个可以用于结构成员并与继承相关的关键字是new和override,当创建一个和基类System.ValueType的成员有相同名称的成员时使用它们。
装箱和拆箱
如同其他值类型数据,如果想将一个结构实例作为引用类型对象,必须创建装箱(boxing)副本。装箱的过程就是制作值类型变量的引用类型副本。装箱和拆箱(unboxing)在第16章详述。
6个重要的.NET概念: - 堆栈,堆,值类型,引用类型,装箱和拆箱
结构作为返回值和参数
结构可以作为返回值和参数
- 返回值 当结构作为返回值时,将创建它的副本并从函数成员返回
- 值参数 当结构作为值参数时,将创建实参结构的副本。该副本用于方法的执行中
- ref和out参数 若把一个结构用作ref或out参数,传入方法的是结构的引用,这样就可以修改其数据成员
关于结构的其他信息
对于结构进行分配比创建类的实例开销小,所以使用结构替代类有时可以提高性能,但要注意到装箱和拆箱的高代价。
关于结构,需要知道的最后一些事情如下:
- 预定义简单类型(int、short、long等等),尽管在.NET和C#中被视为原始类型,它们实际上在.NET中都实现为结构
- 可以使用与声明分部类相同的方法声明分部结构,如第6章所述。
结构和类一样,可以实现接口。接口将在第15章阐述。
C#图解教程 第十章 结构的更多相关文章
- C#图解教程 第二十章 异步编程
笔记 异步编程 什么是异步 示例 async/await特性的结构什么是异步方法 异步方法的控制流await表达式取消一个异步操作异常处理和await表达式在调用方法中同步地等待任务在异步方法中异步地 ...
- C#温故知新:《C#图解教程》读书笔记系列
一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...
- 《C#图解教程》读书笔记之二:存储、类型和变量
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.类型初窥:掀起你的盖头来 (1)C程序是一组函数和数据类型,C++程序是一组函数和类,而C#程序是一组类型声 ...
- 《C#图解教程》读书笔记之三:方法
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.方法那些事儿 (1)方法的结构:方法头—指定方法的特征,方法体—可执行代码的语句序列: (2)方法的调用:参 ...
- Blend4精选案例图解教程(二):找张图片玩特效
原文:Blend4精选案例图解教程(二):找张图片玩特效 Blend中的特效给了我们在处理资源时更多的想象空间,合理地运用特效往往会得到梦幻般效果,本次教程展示对图片应用特效的常规操作,当然特效不仅限 ...
- win8.1系统的安装方法详细图解教程
win8.1系统的安装方法详细图解教程 关于win8.1系统的安装其实很简单 但是有的童鞋还不回 所以今天就抽空做了个详细的图解教程, 安装win8.1系统最好用U盘安装,这样最方便简单 而且系统安装 ...
- Zabbix3.x安装图解教程
准备知识: Zabbix3.x比较之前的2.0界面有了很大的变化,但是安装部署过程与2.x基本完全一样. 1.Zabbix2.x安装图解教程 http://www.osyunwei.com/archi ...
- 《C#图解教程》读书笔记之一:C#和.NET框架
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.在.NET之前的编程世界 C#语言是在微软公司的.NET框架上开发程序而设计的,首先作者给大家纠正了一下C# ...
- 《C#图解教程》读书笔记之四:类和继承
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.万物之宗:Object (1)除了特殊的Object类,其他所有类都是派生类,即使他们没有显示基类定义. ( ...
随机推荐
- poj1265&&2954 [皮克定理 格点多边形]【学习笔记】
Q:皮克定理这种一句话的东西为什么还要写学习笔记啊? A:多好玩啊... PS:除了蓝色字体之外都是废话啊... Part I 1.顶点全在格点上的多边形叫做格点多边形(坐标全是整数) 2.维基百科 ...
- MessagePack简析
一.MessagePack是什么 先看官方的定义:MessagePack是一种高效的二进制序列化格式.它允许您像JSON一样在多个语言之间交换数据.但是,它更快并且更小. 从官方定义中,可以有如下的结 ...
- Material使用11 核心模块和共享模块、 如何使用@angular/material
1 创建项目 1.1 版本说明 1.2 创建模块 1.2.1 核心模块 该模块只加载一次,主要存放一些核心的组件及服务 ng g m core 1.2.1.1 创建一些核心组件 页眉组件:header ...
- 讲解mybaits的标签语法
前言:mybatis作为一个持久层的java框架,高度封装了jdbc原始代码,它拥有比Hiberante更便捷.更直接的sql语法和sql灵活配置的特性,比如简单的一个自动映射对象就大大减少了我们的代 ...
- Chrome Stylist 插件 (CSS备份)
Stylist 插件还是很好用的,可以给网站自定义CSS样式,(还有个插件叫"油猴子",可以给网页加载自定义JS): 不过麻烦的是,现在的最新版360浏览器不能显示这个插件(这个浏 ...
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...
- java 流输出的一些问题
一.java流的控制首先要先准备一个文件,例如:File f = new File(d:/lol.txt); 二.可以使用如下指令创建流,用于不同的用途 1.FileInputStream,FileO ...
- 对于文件File类型中的目录分隔符
当我们在使用File f=new File(path); 对于这个path来说是一个很痛苦的事情,在不同的系统上面的分隔符号是不一样的 在windows下面的话是一个"\"而在un ...
- Sublime Text编辑远程Linux服务器上的文件
sublime有个叫sftp的插件,可以通过它直接打开远程机器上的文件进行编辑,并在保存后直接同步到远程linux服务器上. 用Package Control安装插件 按下Ctrl+Shift+P调出 ...
- 情景linux--如何解决read命令产生的硬编码问题
情景 我们知道,read命令可以读取文件内容,并把内容赋值给变量. 以如下的数据文件为例. $ cat data.txt 1 201623210021 wangzhiguo 25 2 20162321 ...