【C#学习笔记】引用类型(1)

在这里插入图片描述

文章目录

  • 引用类型
    • class
      • 匿名类
    • 记录
      • 引用相等和值相等
      • record声明
    • 接口
    • delegate 委托
      • 合并委托/多路广播委托


引用类型

引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。 对于引用类型,两种变量可引用同一对象;因此,对一个变量执行的操作会影响另一个变量所引用的对象。 对于值类型,每个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另一个变量(in、ref 和 out 参数变量除外)。

在前文中,我们常常说引用类型比值类型要好,一方面引用类型的对象类似于指针,不同的变量会指向同一个对象。而值类型则是将定义的值克隆一个副本赋值给新的变量。从性能方面引用类型就更好,并且从内存方面考虑,引用类型存放在CLR的虚拟机堆中,而值类型存放在栈中,在堆中可以对数据直接处理,而在栈中则需要将其前面的内存出栈,从内存方面使用引用类型也更好。而具体的关于引用和值类型在内存中的关系,将在未来GC的章节中描述。

在这里插入图片描述


class

类应该是最熟悉的一种引用类型了

class ClassA { } --直接定义类
class DerivedClass : BaseClass { } --继承单个类
class ImplClass : IFace1, IFace2 { } -- 实现两个接口
class ImplDerivedClass : BaseClass, IFace1 { } --继承一个类,实现一个接口

在C#中,我们只能继承一个类,但是可以继承多个接口。(看到本文,我默认你学过面向对象了)

匿名类

匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。

var v = new { Amount = 108, Message = "Hello" };
// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);  //108Hello

使用匿名类,我们定义新的对象的时候可以不必定义一个类,这是为了方便我们进行一些对象的生成,特别是当这个类是临时定义的,只需要属性而不需要其他方法,且有可能只会定义一次对象的时候。

匿名类型包含一个或多个公共只读属性。 包含其他种类的类成员(如方法或事件)为无效。 用来初始化属性的表达式不能为 null、匿名函数或指针类型。

在下例中,我们用prod遍历了products集合,并在每次创建一个新的匿名类,其中属性为Color和Pirce

var productQuery =from prod in productsselect new { prod.Color, prod.Price };foreach (var v in productQuery)
{Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

尽管我们并没有给匿名类中的属性创建变量名,但是匿名类自动的将创建时的变量名作为了自己的变量名,也就是创建时使用了prod.Color,prod.Price。它根据变量名为自己的属性也创建了相应的同名变量ColorPrice

还可以按另一种类型(类、结构或另一个匿名类型)的对象定义字段。 它通过使用保存此对象的变量来完成,如以下示例中所示,其中两个匿名类型是使用已实例化的用户定义类型创建的。 在这两种情况下,匿名类型 shipment shipmentWithBonus 中的 product 字段的类型均为 Product,其中包含每个字段的默认值。 bonus 字段将是编译器创建的匿名类型。

var product = new Product();
var bonus = new { note = "You won!" };
var shipment = new { address = "Nowhere St.", product };
var shipmentWithBonus = new { address = "Somewhere St.", product, bonus };

在上述例子中我们可以看到,匿名类本身的属性通常不需要定义类型,而类型是由编译器自己决定的。而已有类型定义的变量则是其对应的类型,例如product的类型是Product,而bonus的类型则是匿名类。
由于匿名类的类型是不定的,因此使用var关键字来定义这个匿名类。

如果想要修改匿名类中的属性,可以使用with表达式来实现:

var apple = new { Item = "apples", Price = 1.35 };
var onSale = apple with { Price = 0.79 };
var Banana = apple with {}; // 使用with空值可以直接赋值

(注意,with和record只能在C# 9以上的版本使用,unity中暂时不可用)


记录

记录是一个类或者结构体,通过添加record修饰符声明,

在下列情况下,请考虑使用记录而不是类或结构:

  • 你想要定义依赖值相等性的数据模型。
  • 你想要定义对象不可变的类型。

值相等性的意思是两个作为相等比较的值,只有当它们类型相等,且属性的属性名相等且属性值相等,才能视为相等。类似于内部的键值对需要完全相等。更具体的来说,一般而言的相等性是引用相等性,其相等比较在于:如果两个类型引用同一个变量则认为它们相等。

不可变性就是在对象实例化后禁止更改该对象的任何属性或字段值。

引用相等和值相等

为了清楚引用相等和值相等,请看下面几个例子:

Product A = new Product();
Product B = new Product();
if (A == B)
{Debug.Log(1);  --输出不了
}

第一个例子中,A==B是false的,因为A和B作为引用类型,它们的引用不相等

Product A = new Product();
Product B = A;
if (A == B)
{Debug.Log(1);  --输出1
}

在第二个例子中,B引用A,而A引用的是new Product(),所以二者引用相等。

值相等应当不必解释了,就是平常意义上的相等

record声明

var phoneNumbers = new string[2];
Person person1 = new("Nancy", "Davolio", phoneNumbers);
Person person2 = new("Nancy", "Davolio", phoneNumbers);
Console.WriteLine(person1 == person2); // output: Trueperson1.PhoneNumbers[0] = "555-1234";
Console.WriteLine(person1 == person2); // output: TrueConsole.WriteLine(ReferenceEquals(person1, person2)); // output: False

接口

接口是高度抽象的,我们可以使用interface关键字定义一个接口,在接口中我们只应当定义函数头,其内部实现则完全由继承了接口的类来实现。

interface IEquatable<T>
{bool Equals(T obj);
}

一个接口同样可以继承其他的接口,当一个接口继承多个其他接口后,这个接口被称为派生接口,其他接口被称为基接口。一个继承了派生接口的类,不仅需要实现派生接口中的所有方法,也需要实现基接口中的所有方法:

interface IBaseInterface
{void BaseMethod();
}
interface IEquatable : IBaseInterface
{bool Equals();
}
public class TestManager : IEquatable
{bool IEquatable.Equals(){throw new NotImplementedException();}void IBaseInterface.BaseMethod(){throw new NotImplementedException();}
}

delegate 委托

委托的使用通常需要将方法作为参数传递给其他方法时。可以将委托视为调用一个事件时会触发的方法。相当于我们不必在事件或者函数内部定义一个回调参数,而只需要把委托方法附加上去即可。

相较于接口,委托更适合灵活的方法组合,可以添加给多个事件。用我个人的理解来比喻,点餐是一个事件,假设这个饭店能APP点餐和服务员点餐,而APP只能点套餐,服务员可以一个菜一个菜给你加。现在我们分别要用委托和接口实现这个事件。委托像是有个服务员帮你点餐,你只需要说想吃什么,服务员就会帮你记下然后通知后厨。而接口像捆绑了一堆的套餐,如果点了鸡腿套餐,那一定会给你鸡腿+米饭,点了猪排套餐一定给你猪排+米饭。而使用委托,如果我们想要鸡腿+米饭,我们也可以让服务员给我们增加两个菜(方法),一个是鸡腿,一个是米饭。但是如果我们想要的菜品多,且和套餐重复的话,那么接口可以更好的实现。但如果我们想要灵活地点菜,例如我想要鸡腿+米饭,用接口实现了,然后我又想要一个猪排,如果用接口实现那接口会给我猪排+米饭。如果我只想要猪排那就应该叫服务员来,只点一个猪排。

委托可以和方法绑定,当触发委托时自动触发绑定的方法

// Declare a delegate:
delegate void Del(int x);// Define a named method:
void DoWork(int k) { /* ... */ }// Instantiate the delegate using the method as a parameter:
Del d = obj.DoWork;

合并委托/多路广播委托

不同的委托之间可以合并:

CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;hiDel = Hello;
byeDel = Goodbye;
multiDel = hiDel + byeDel;
multiMinusHiDel = multiDel - hiDel;

委托的合并直接使用加法即可,简单来说委托A+委托B =合并委托C,而合并委托C可以使用减法把委托A或者委托B减掉。加法就像服务员A和服务员B跟厨师说1号桌要XXX菜,2号桌要XXX菜,厨师肯定是哪桌先点餐哪桌先上菜。减法就是服务员B过来又说2号桌不要了,你别做了,那厨师只做服务员A委托的1号桌的菜就好了。

在调用多播委托时,它会按顺序调用列表中的委托。 只能合并相同类型的委托。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/77477.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10.物联网操作系统之低功耗管理

一。低功耗管理概念及其应用 1.STM32低功耗设计详解 STM32的电源管理系统主要分为&#xff1a; 备份域 调压器供电电路 ADC电源电路 2.低功耗模式 1.运行模式 2.睡眠模式 3.停机模式 4.待机模式 &#xff08;1&#xff09;睡眠模式 在睡眠模式中&#xff0c;仅关闭了内核时钟&…

数据结构——二叉树

本章代码仓库&#xff1a;堆、二叉树链式结构 文章目录 &#x1f36d;1. 树&#x1f9c1;1.1 树的概念&#x1f9c1;1.2 树的结构 &#x1f36c;2. 二叉树&#x1f36b;2.1 二叉树的概念&#x1f36b;2.2 特殊的二叉树&#x1f36b;2.3 二叉树的性质&#x1f36b;2.4 二叉树的存…

Julia 日期和时间

Julia 通过 Dates 模块提供了以下三个函数来处理日期和时间&#xff1a; Date&#xff1a;表示日期&#xff0c;精确到日&#xff0c;只显示日期。DateTime&#xff1a;表示日期和时间&#xff0c;精确到毫秒。DateTime&#xff1a;表示日时间&#xff0c;精确到纳秒&#xff…

【数据库】将excel数据导入mysql数据库

环境&#xff1a;Windows10 mysql8以上 将你要导入的excel表另存为txt格式 打开txt格式文件&#xff0c;删除表头行并另存为并更改编码方式&#xff08;由于与数据库的编码不同&#xff0c;会导致导入报错&#xff09; 通过命令行登录数据库 winr cmd进入 进入装mysql的目录位…

基于BIM+AI的建筑能源优化模型【神经网络】

推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 AEC&#xff08;建筑、工程、施工&#xff09;行业的BIM 技术&#xff0c;允许在实际施工开始之前虚拟地建造建筑物&#xff1b; 这带来了许多有形和无形的好处&#xff1a;减少成本超支、更有效的协调、增强决策权等等。…

Windows批处理基础

一、【echo】显示文本内容 echo | Microsoft Learnhttps://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/echo 显示消息或者打开或关闭命令回显功能。 如果不结合任何参数使用&#xff0c;echo 会显示当前回显设置。 1.1、echo显示文本常用命…

AIGC大模型ChatGLM2-6B:国产版chatgpt本地部署及体验

1 ChatGLM2-6B介绍 ChatGLM是清华技术成果转化的公司智谱AI研发的支持中英双语的对话机器人。ChatGLM基于GLM130B千亿基础模型训练&#xff0c;它具备多领域知识、代码能力、常识推理及运用能力&#xff1b;支持与用户通过自然语言对话进行交互&#xff0c;处理多种自然语言任务…

【SQL】-【计算两个varchar类型的timestamp的毫秒差】

背景 TRANSTAMP3、TRANSTAMP2在Oracle数据库中的类型为varchar&#xff0c;但实际保存的值是时间戳timestamp类型&#xff0c;现在要计算二者的毫秒差 Oracle或MySQL extract(second from (to_timestamp(TRANSTAMP3,yyyy-mm-dd hh24:mi:ss.ff) - to_timestamp(TRANSTAMP2,yyy…

运放电路之比较器的分析笔记

一、比较器 比较器分为同相比较器和反相比较器。 反相比较器电路如下&#xff1a; V11为固定值&#xff0c;这里设定的是2.5V&#xff0c;接到了运放的输入正&#xff08;V&#xff09;&#xff1b; V10为输入值&#xff0c;值可变&#xff0c;接到了运放的输入负&#xff08;V…

CADintosh X for mac CAD绘图软件2D CAD 程序 兼容 M1

CADintosh X for Mac是一个功能强大的2D CAD绘图程序&#xff0c;专为Mac用户设计。它由Lemke Software开发&#xff0c;提供了一套丰富的工具和功能&#xff0c;使用户能够轻松创建高质量的技术图纸&#xff0c;平面图和设计。 CADintosh X for Mac具有直观的用户界面&#x…

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14)

文章目录 通过外部中断实现按键捕获代码的实现及分析Tip1:函数说明的格式Tip2:如何使用CMSIS的延时GetTick函数原型stm32f407_intr_handle.c解析中断处理函数&#xff1a;void EXTI4_IRQHandler 调试流程软件模拟调试 两种代码的比较课后作业: 通过外部中断实现按键捕获代码的实…

装修小程序,开启装修公司智能化服务的新时代

随着数字化时代的来临&#xff0c;装修小程序成为提升服务质量和效率的关键工具。装修小程序旨在为装修公司提供数字化赋能、提高客户满意度的智慧装修平台。通过装修小程序&#xff0c;装修公司能够与客户进行在线沟通、展示设计方案、提高服务满意度等操作。 装修小程序的好处…

8月5日上课内容 nginx的优化和防盗链

全部都是面试题 nginx的优化和防盗链 重点就是优化&#xff1a; 每一个点都是面试题&#xff0c;非常重要&#xff0c;都是面试题 1、隐藏版本号&#xff08;重点&#xff0c;一定要会&#xff09; 备份 cp nginx.conf nginx.conf.bak.2023.0805 方法一&#xff1a;修改配…

HTML 是什么?它的全称是什么?

聚沙成塔每天进步一点点 专栏简介HTML是什么&#xff1f;HTML的全称是什么&#xff1f;写在最后 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对We…

【大模型】开源且可商用的大模型通义千问-7B(Qwen-7B)来了

【大模型】开源且可商用的大模型通义千问-7B&#xff08;Qwen-7B&#xff09;来了 新闻通义千问 - 7B 介绍评测表现快速使用环境要求安装相关的依赖库推荐安装flash-attention来提高你的运行效率以及降低显存占用使用 Transformers 运行模型使用 ModelScope 运行模型 量化长文本…

2配置篇:基础功能配置

前言 在上一章节中,我们学习了 NestJS CLI 的用法,得到了一套基础的项目工程。最开始做项目对比的时候也提到过,NestJS 作为一款自定义程度较高的框架,CLI 直接提供的基础功能虽然并不完善,但同时也为开发者提供了非常多的内置或配套的功能例如高速缓存、日志拦截、过滤器…

阿里云平台WoSignSSL证书应用案例

沃通CA与阿里云达成合作并在阿里云平台上线WoSign品牌SSL证书。自上线以来&#xff0c;WoSignSSL证书成为阿里云“数字证书管理服务”热销证书产品&#xff0c;获得阿里云平台客户认可&#xff0c;助力阿里云平台政府、金融、教育、供应链、游戏等各类行业客户实现网站系统数据…

macOS下Django环境搭建

1. macOS升级pip /Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip 2. 卸载Python3.9.5版本 $ sudo rm -rf /usr/local/bin/python3 $ sudo rm -rf /usr/local/bin/pip3 $ sudo rm -rf /Library/Frameworks/Python.framework 3. 安装P…

IO多路转接之select

IO多路转接之select 1. 初识select 系统提供select函数来实现多路复用输入/输出模型。 select系统调用是用来让我们的程序监视多个文件描述符的状态变化的&#xff1b;程序会停在select这里等待&#xff0c;直到被监视的文件描述符有一个或多个发生了状态改变&#xff1b; …