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 ...
随机推荐
- Docker在树莓派的安装与使用(Ubuntu Arm Server v19.10)
最近由于冠状病毒疫情的原因,只能够和小朋友家里蹲.这几天把尘封已久的那个树莓派拿出来继续捣鼓.希望能够做一个异构的分布式系统框架,于是想把Docker也安装到树莓派上,以便后期做进一步的开发和实验. ...
- DNS隧道基础
DNS协议是一种请求/应答协议,也是一种可用于应用层的隧道技术.虽然激增的DNS流量可能会被发现,但基于传统socket隧道已经濒临淘汰鸡TCP.UDP通信大量被防御系统拦截的状况,DNS.ICMP. ...
- centos7安装mysql-5.7.28
mysql是我们最常用的开源的关系型数据库,mysql不同版本有时候安装的方式也不尽相同,下面以mysql5.7.28版本为例梳理一下安装细节: 1.下载mysql-5.7.28,URL:https: ...
- hashmap 的边遍历边存储
PS: Hashmap 的一边遍历边存储,可解决例如两数之和. 无重复最长子串问题等,代码为cpp格式. 以无重复最长子串为例. class Solution { public: int length ...
- ROS机器人之话题(一)
将消息发布到话题上 首先建立一个basic包(名称自己定)其命令为: 1.创建功能包,应用catkin_create_pkg命令 cd ~/catkin_ws/src #切换到代码空间,也 ...
- Spring-cloud微服务实战【八】:API网关zuul
在前面的文章中,我们先后使用了eureka/ribbon/feign/hystrix搭建了一个看似完美的微服务了,那是否还有值得继续优化的地方呢?答案肯定是有的,如果从整个微服务内部来看,基本已经 ...
- DOCKER 学习笔记7 Docker Machine 建立虚拟机实战,以及错误总结
前言 通过以上6小节的学习,已经可以使用DOCKER 熟练的部署应用程序了.大家都可以发现使用 DOCKER 带来的方便之处,因为现在的话,只是在一台服务器上部署,这样部署,我们只需要一条命令,需要的 ...
- Spring配置 bean
在 Spring 的 IOC 容器里配置 Bean <bean id="helloWorld" class="com.xiya.spring.beans.Hello ...
- tensorflow MNIST Convolutional Neural Network
tensorflow MNIST Convolutional Neural Network MNIST CNN 包含的几个部分: Weight Initialization Convolution a ...
- Codeforces_723_A
http://codeforces.com/problemset/problem/723/A 取中间那个数就可以了,答案为最大值减最小值. #include<iostream> #incl ...