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 ...
随机推荐
- STL中的vector 和list
参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第十章 认识两个容器:vector和list 容器:是STL(Standard Template Library 标准模板库 ...
- 【vue_django】成功登录后,保存用户
PS:使用session 保存: // 登录 login() { if (this.username === "" || this.password === "" ...
- Python用WMI模块获取windowns系统信息
安装vmi https://pypi.org/project/WMI/#history 脚本如下: #!/usr/bin/env python #coding:utf- import wmi impo ...
- mysql随机查询若干条数据
条不重复的数据,使用以下: 秒以上 搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据. SELECT * FROM `table` AS t1 JOIN (SELE ...
- java(list,set,map)链接
http://blog.csdn.net/smileiam/article/details/49836865 http://blog.csdn.net/u013344815/article/detai ...
- 2018icpc南京现场赛-I Magic Potion(最大流)
题意: n个英雄,m个怪兽,第i个英雄可以打第i个集合里的怪兽,一个怪兽可以在多个集合里 有k瓶药水,每个英雄最多喝一次,可以多打一只怪兽,求最多打多少只 n,m,k<=500 思路: 最大流, ...
- 分组密码CBC加密缺陷
title: 分组密码CBC加密缺陷 date: 2017-05-15 10:04:47 tags: ["密码学"] --- 关于密码学的种种漏洞以及利用网上也有不少,但是比较零散 ...
- pytorch-- Attention Mechanism
1. paper: Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translat ...
- pytorch之 Variable
import torch from torch.autograd import Variable # Variable in torch is to build a computational gra ...
- 数据算法 --hadoop/spark数据处理技巧 --(9.基于内容的电影推荐 10. 使用马尔科夫模型的智能邮件营销)
九.基于内容的电影推荐 在基于内容的推荐系统中,我们得到的关于内容的信息越多,算法就会越复杂(设计的变量更多),不过推荐也会更准确,更合理. 本次基于评分,提供一个3阶段的MR解决方案来实现电影推荐. ...