C#编程(十八)----------C#中的结构
C#中的结构
假设有一个类:
class Dimensions
{
public double Length;
public double Width;
}
定义了一个类,它只存储某一项的长度和宽度.嘉定编写一个布置家居的程序,让人们试着在计算机上重新布置家具,并存储每件家具的维度.使字段变为共有字段,就会违背变成规则,但我们实际上并不需要类的全部功能.现在只有两个数字,把他们当做一堆来处理,要比单个处理方便一些.既不需要很多方法,也不需要从类中继承,也不希望.NET运行库在堆中遇到麻烦和性能问题,值存储两个double类型的数据即可.
为此,只需要修改代码,使用关键字struct代替class,定义一个结构而不是类
struct Dimensions
{
public double Length;
public double Width;
}
为结构定义函数与味蕾定义函数完全相同.
struct Dimensions
{
public double Length;
public double Width;
public Dimensions(double length, double width)
{
this.Length = length;
this.Width = width;
}
public double Diagonal
{
get
{
return Math.Sqrt(Length * Length + Width * Width);
}
}
}
结构是值类型,不是引用类型.他们存储在栈中或存储为内联,其生存期的限制与简单的数据类型一样.
结构不支持继承.
对于结构构造函数的工作方式有一些区别.尤其是编译器总是提供一个无参数的默认构造函数,他是不允许替换的.
使用结构,可以指定字段如何在内存中的布局.
因为结构实际上是把数据项组合在一起,有时大多数或者全部的字段都声明为public.严格来说,这是违背.NET代码的规则的,根据Microsoft,字段(除了const字段之外)应该总是私有的,并由共有属性封装.但是对于简单的结构,共有字段还是可以接受的.
结构是值类型
虽然结构是值类型,但是在语法上常常可以把他们当做类来处理.例如,上面的Dimension类的定义中,可以编写下面的代码:
Dimensions point = new Dimensions();
point.Lenth=3;
point.Width=6;
注意,因为结构是值类型,所以new运算符与类和其他引用类型的工作方式不同.new运算符并不分配队中的内存,而是只调用相应的构造函数,根据传送给他的参数,初始化所有的字段.对于结构,可以编写下面代码:
Dimensions point;
point.Length=3;
point.Width=6;
如果Dimensions是一个类,就会产生错误,因为point包含一个为初始化的引用----不知想任何地方的一个地址,所以不能给其字段设置值.但是对于结构,变量声明实际上是维护整个结构在栈中分配空间,所以就可以为他赋值了.
但是如果这样:
Dimensions point;
double d=point.Length;
编译器就会产生一个错误,原因是使用了未初始化的变量.
结构遵循其他数据类型都遵循的规则:在使用前所有的元素都必须进行初始化.在结构上调用new运算符,或者给所有的字段分别赋值,结构就完全初始化了.如果结构定义为类的成员字段,在初始化包含的对象时,该结构会自动初始化为0.
结构是会影响性能的值类型.
结构不失为继承设计的.这意味着:他不能从一个结构中继承.唯一的例外是对应的结构(和C#中的其他类型一样)最终派生于类System.Object.因此结构可以访问System.Object的方法.在结构中,甚至可以重写System.Objetc中的方法----如重写ToString()方法.结构的继承链是:每个结构派生自System.ValueType类,System.ValueType类又派生自System.Object.ValueType并没有给Object添加任何新成员,但提供了一些更适合结构的额实现方式.注意,不能为结构提供其他类:每个结构都派生自ValueType.
结构的构造函数
为结构定义构造函数的方式与为类定义构造函数的方式相同,但不允许定义无参数的构造函数.禁止在C#的结构内使用无参数的构造函数.
前面说过,默认构造函数把数值字段都初始化为0,把引用类型字段初始化为null,且总是隐式的给出,及时提供了其他带参数的构造函数,也是如此,提供字段的初始值也不鞥呢绕过默认构造函数.
例如:
struct Dimensions
{
public double Length=1;
public double Width=2;
}
会出现错误,结构中不能有实例字段初始值设定项,如果是类就不会出现这个错误.
另外,可以向类那样为结构提供Close()或Dispose()方法.
struct总结:struct 类型适于表示 Point、Rectangle 和 Color 等轻量对象。为结构定义默认(无参数)构造函数是错误的。 在结构体中初始化实例字段也是错误的。 只能通过两种方式初始化结构成员:一是使用参数化构造函数,二是在声明结构后分别访问成员。 对于任何私有成员或以其他方式设置为不可访问的成员,只能在构造函数中进行初始化。
如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当的构造函数。 与类不同,结构的实例化可以不使用 new 运算符。 在此情况下不存在构造函数调用,因而可以提高分配效率。 但是,在初始化所有字段之前,字段将保持未赋值状态且对象不可用。
当结构包含引用类型作为成员时,必须显式调用该成员的默认构造函数,否则该成员将保持未赋值状态且该结构不可用。 (这将导致编译器错误 CS0171。)
对于结构,不像类那样存在继承。 一个结构不能从另一个结构或类继承,而且不能作为一个类的基。 但是,结构从基类 Object 继承。 结构可实现接口,其方式同类完全一样。
无法使用 struct 关键字声明类。 在 C# 中,类与结构在语义上是不同的。 结构是值类型,而类是引用类型。
C#编程(十八)----------C#中的结构的更多相关文章
- 漫谈程序员(十八)windows中的命令subst
漫谈程序员(十八)windows中的命令subst 用法格式 一.subst [盘符] [路径] 将指定的路径替代盘符,该路径将作为驱动器使用 二.subst /d 解除替代 三.不加任何参数键入 ...
- YbSoftwareFactory 代码生成插件【十八】:树形结构下的查询排序的数据库设计
树形结构的排序在中国特色下十分普遍也非常重要,例如常说的五大班子,党委>人大>政府>政协>纪委,每个班子下还有部门,岗位,人员,最终排列的顺序通常需要按权力大小.重要性等进行排 ...
- Java学习笔记二十八:Java中的接口
Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...
- Unix环境高级编程(十八)高级进程间通信
本章主要介绍了基于STREAM的管道和UNIX域套接字,这些IPC可以在进程间传送打开文件描述符.服务进程可以使用它们的打开文件描述符与指定的名字相关联,客户进程可以使用这些名字与服务器进程通信. 1 ...
- java web学习总结(二十八) -------------------JSP中的JavaBean
一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...
- WPF入门教程系列十八——WPF中的数据绑定(四)
六.排序 如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider.CollectionViewSource 则会 ...
- (十八)WebGIS中清空功能和地图定位功能的设计以及实现
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 当地图中增加了很多元素后,对不同的元素需要进行一定的控制,最 ...
- python学习(十八)爬虫中加入cookie
转载自:原文链接 前几篇文章介绍了urllib库基本使用和爬虫的简单应用,本文介绍如何通过post信息给网站,保存登陆后cookie,并用于请求有权限的操作.保存cookie需要用到cookiejar ...
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
随机推荐
- php毫秒时间戳
2014年5月23日 17:46:04 凡事还是得靠自己呀,网上太多坑 如果你的机器是 32位 的可以看这个: list($usec, $sec) = explode(' ', microtime() ...
- TypeError: Object of type 'int64' is not JSON serializable
错误类型:TypeError: Object of type 'int64' is not JSON serializable 错误场景:对Numpy和Pandas结果进行json.dumps报错 错 ...
- Python_oldboy_常用模块(九)
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & pickle shelve xml处理 yaml处理 configpar ...
- P1855 榨取kkksc03 二维费用背包
Kkksc03的时间和金钱是有限的,所以他很难满足所有同学的愿望.所以他想知道在自己的能力范围内,最多可以完成多少同学的愿望? 输入输出格式 输入格式: 第一行,n M T,表示一共有n(n<= ...
- Java之路(四)数组初始化
本文主要讲数组的初始化方法.可变参数列表以及可变参数列表对函数重载的影响. 1.数组初始化 定义数组的方式: int[] arr1; 或 int arr1[]; 数组初始化 通过上边的定义,我们只是 ...
- 最小生成树问题(prim算法)POJ-1258 Agri-Net
/* 这个题很水,但是,莫名其妙runtime error一晚上,重写了一遍就又没了,很伤心! 题意很简单,大致为n个村庄,连光缆,要求连上所有村庄的长度最短. 输入n,接着是n*n的矩阵,直接用pr ...
- Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Maven)
写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) 我这里,相信,能看此博客的朋友,想必是有一定基础的了.我前期写了大量的基础性博文. ...
- tqdm:Python 进度条
Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息.用户只需要封装任意的迭代器,是一个快速.扩展性强的进度条工具库. 用法:tqdm(iterator) 代码地址 ...
- DIM-00014: Cannot open the Windows NT Service Control Manager.
创建Oracle数据库时出错: OPW-00001: Unable to open password-file DIM-00014: Cannot open the Windows NT Servic ...
- 【BZOJ】3751: [NOIP2014]解方程【秦九韶公式】【大整数取模技巧】
3751: [NOIP2014]解方程 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4856 Solved: 983[Submit][Status ...