C#面向对象--结构
一、结构(Struct)是CTS中五种基本类型之一,是一种值类型,同样封装了同属一个逻辑单元的数据和行为,这些数据和行为通过结构中的成员表示;结构与类共享大多数相同的语法,但结构比类受到的限制更多,结构适用于表示轻量级类型;使用struct关键字定义结构:
//定义一个公共结构MyStruct
public class MyStruct
{
public int MyField; //声明一个int类型的公共实例字段
public void MyFunc() //声明一个公共实例方法
{
//do…
}
}
1.所有结构都直接隐式继承自System.ValueType,不能再指定继承自其它任何结构或类,即结构不支持继承,但可以实现一个或多个接口,同时结构也是隐式密封的,不能被继承;
※将结构类型的对象强制转换为其所实现的任何接口类型或object类型时会导致装箱操作,此时会将结构类型的对象包装到托管堆内存上的引用类型对象内;
2.由于结构不支持继承,因此结构不能被定义为abstract或sealed;
3.结构不能被定义为静态的,但可以声明静态成员;
4.由于结构不支持继承,因此结构成员只能声明为public、internal或private的,不能声明为abstract、virtual和sealed;
※对于实例成员,不能在结构声明中直接对其进行初始化;
※对于静态成员,可以在声明时进行初始化,也可以在静态构造函数中对其初始化;
※结构中不能声明默认构造函数(无参数的构造函数),结构的默认构造函数由编译器保留,并一直处于可用状态,其作用是申请指定大小的内存空间,并将所有字节初始化为0(即default(T));
※结构中可以声明带参数的自定义构造函数,自定义构造函数的方法体中必须对所有的实例成员进行初始化,否则编译器会报错,私有实例成员只能在构造函数中进行初始化;
※结构不存在析构阶段,不能声明析构函数;
public struct MyStruct
{
public int MyNum;
public string MyStr; public static int MyStaticNum = ; public MyStruct(int myNum,string myStr)
{
MyNum = myNum;
MyStr = myStr;
} static MyStruct()
{
//对于静态成员,可以直接在声明时初始化,也可以在静态构造函数中初始化
//MyStaticNum = 1;
}
}
二、可以通过调用默认构造函数、自定义构造函数、使用对象初始化器或在声明结构之后单独初始化成员的方式构建结构实例;
1.使用运算符new或运算符default构建结构实例,并调用对应的构造函数:
MyStruct myStruct = new MyStruct(); //调用结构的默认构造函数,此时MyNum为0,MyStr为null
myStruct = default(MyStruct); //与使用new MyStruct()完全等效
myStruct = new MyStruct(, ""); //调用结构的自定义构造函数
2.与类不同,结构的实例化可以不使用new运算符,此时不会调用任何构造函数,也不会初始化任何实例成员,内存分配效率提高,在访问某个实例字段之前对该字段初始化即可:
MyStruct myStruct; //构建结构实例,但不调用构造函数
myStruct.MyNum = ;
int myNum = myStruct.MyNum; //访问某个实例成员之前需要对其初始化
※通常适用于只使用结构中部分实例字段进行存储和操作的情况;
※只有当所有的实例字段都初始化完成后,才能调用其实例方法或将其用作参数、返回值;
※结构中存在私有实例字段时也可以使用此种方式构建结构实例,但也意味着不能初始化完成其所有实例字段;
三、结构是值类型,变量和数据放在一起,对结构类型的变量进行赋值、传递参数、方法返回等操作时都会产生新的变量,并会复制(即浅拷贝)原变量中的所有数据到新变量中,对新变量所做的任何修改都不会改变原变量的数据,只能将新变量重新赋值给原变量,在处理值类型的集合(如List<MyStruct>)时需要格外注意这点:
//当需要修改值类型集合中某个元素的数据时,需要先拿一个变量接收,修改完成后再赋值给集合
MyStruct myStruct = myStructList[];
myStruct.MyNum = ;
myStructList[] = myStruct;
1.结构类型可用作可空类型,此时依然是值类型,可空类型的变量可赋值为null;
MyStruct? myStruct = null;
四、自定义结构的最佳实践:
public struct MyStruct : IEquatable<MyStruct> //实现IEquatable<T>接口用于泛型
{
public int MyNum; public override bool Equals(object obj) //会对实参进行装箱
{
if (!(obj is MyStruct))
{
return false;
}
MyStruct other = (MyStruct)obj; //拆箱
return this.Equals(other);
}
public override int GetHashCode() //避免使用散列集合类时装箱并提供高效实现
{
return MyNum.GetHashCode();
}
public override string ToString() //避免装箱
{
return MyNum.ToString();
} public bool Equals(MyStruct other) //避免比较时实参装箱,避免使用泛型时装箱
{
return this.MyNum == other.MyNum;
}
public static bool operator ==(MyStruct left, MyStruct right) //比较时通常采用==运算符
{
return left.Equals(right);
}
public static bool operator !=(MyStruct left, MyStruct right)
{
return !(left == right);
}
}
※如果需要进行大小比较,还应该实现接口IComparable<T>并重载运算符<=和>=;
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!
作者:Minotauros
出处:https://www.cnblogs.com/minotauros/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
C#面向对象--结构的更多相关文章
- Python面向对象01 /面向对象初识、面向对象结构、类、self、实例化对象
Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 目录 Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 1. 面向对象初识 2. 面向 ...
- python 面向对象专题(一):面向对象初识、面向对象结构、类、self、实例化对象
https://www.cnblogs.com/liubing8/p/11301344.html 目录 Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 1. 面向对象 ...
- C#面向对象 结构体和类的应用
- .NET应用架构设计—面向对象分析与设计四色原型模式(彩色建模、领域无关模型)(概念版)
阅读目录: 1.背景介绍 2.问自己,UML对你来说有意义吗?它帮助过你对系统进行分析.建模吗? 3.一直以来其实我们被一个缝隙隔开了,使我们对OOAD遥不可及 4.四色原型模式填补这个历史缝隙,让我 ...
- OO开发思想:面向对象的开发方法(Object oriented,OO)
面向对象的开发方法(Object oriented,OO)认为是好文章吧,拿来分享一下(转载) 面向对象的开发方法(Object oriented,OO) 从事软件开发的工程 师们常常有这样 的体会: ...
- python 面向对象(一)初识面向对象
##################################总结#################### 1. 面向过程:一切以事物的发展流程为中心 面向对象:一切以对象为中心,一切皆为对向, ...
- day16 初识面向对象
今天主要学习内容: 1.初始面向对象 2 .类 ,对象 3,面向对象和面向过程的对比 4.面向对象的三大特征 1,初始面向对象 面向过程 : 一切以实物的发展流程为中心 面向对象: 一切以对象为中心, ...
- Python 面向对象和面向过程对比
# 大象装冰箱 # 脚本, 此时代码是最简单的. 不需要构思整个程序的概况 print("开门") print("装大象") print("关门&qu ...
- 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装
抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...
随机推荐
- CSS-04-层叠选择器
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 《ASP.NET Core 高性能系列》关于.NET Core的配置信息的若干事项
1.配置文件的相关闲话 Core自身对于配置文件不是必须品,但由上文分析可知ASP.NET Core默认采用appsettings.json作为配置文件,关于配置信息的优先等级 命令行>环境变量 ...
- Java后端开发工程师是否该转大数据开发?
撰写我对java后端开发工程师选择方向的想法,写给在java后端选择转方向的人 背景 看到一些java开发工程师,对java后端薪酬太悲观了.认为换去大数据领域就会高工资.觉得java后端没有前途.我 ...
- 【转】spring framework 5以前体系结构及内部各模块jar之间的maven依赖关系
作者:凌承一 出处:http://www.cnblogs.com/ywlaker/ 很多人都在用spring开发java项目,但是配置maven依赖的时候并不能明确要配置哪些spring的jar, ...
- 快速理解DevOps概念和意义-兼谈SRE
最近几年,由于负责的范围的变化.工作逐渐从某个IT领域或者部门,开始关注到整个IT体系的运转和管理.中间也遇到不少困难,同时也有机会去从更高的层面去学习和实践IT治理.文章主要是总结一下我对DevOp ...
- Codeforces_714_A
http://codeforces.com/problemset/problem/714/A 水,注意K的值. #include <iostream> using namespace st ...
- Spacemacs安装
Spacemacs官网 为什么选择Spacemacs Spacemacs是一个已经配好的Emacs和Vim,正如官网所说的The best editor is neither Emacs nor Vi ...
- 量子计算机编程(一)——QPU编程
今天要给大家介绍的是这本书<Programming Quantum Computers -- Essential Algorithms and Code Samples>,主要讲如何在量子 ...
- sqlserver附加数据库时出错。有关详细信息,请单击“消息”列中的超链接
在SqlServer中附加数据库时,有时会发生下面的错误. 解决 :可能的问题是放置附加数据库的文件夹的权限问题.如下解决.点击放置附加数据库的文件夹-->右键-->属性 权限要设置为完全 ...
- 2020年,手把手教你如何在CentOS7上一步一步搭建LDAP服务器的最新教程
同步滚动:关 什么是LDAP 什么是LDAP? 要想知道一个概念,最简单的办法就是wikipedia,当然也可以百科. LDAP全称是轻型目录访问协议(Lightweight Directory Ac ...