【从零开始入门unity游戏开发之——C#篇21】C#面向对象的封装——`this`扩展方法、运算符重载、内部类、`partial` 定义分部类
文章目录
- 一、`this`扩展方法
- 1、扩展方法的基本语法
- 2、使用扩展方法
- 3、扩展方法的注意事项
- 5、扩展方法的限制
- 6、总结
- 二、运算符重载
- 1、C# 运算符重载
- 2、运算符重载的基本语法
- 3. 示例:重载加法运算符 (`+`)
- 4、使用重载的运算符
- 5、支持重载的运算符
- 6、不能重载的运算符
- 7、运算符重载的注意事项
- 8、总结
- 三、内部类
- 1、**示例:**
- 2、**特点:**
- 四、`partial` 定义分部类
- 1、**示例:**
- 2、**使用:**
- 3、**特点:**
- 专栏推荐
- 完结
一、this扩展方法
扩展方法是 C# 的一项强大特性,它允许你为现有类型(包括系统类型或第三方库中的类型)添加方法,而不需要修改其源代码或继承该类型。扩展方法通常用于增强类的功能,特别是当你无法修改类本身时。
扩展方法的语法非常简单,但它们实际上是静态方法,只是通过特殊的语法“看起来”像是实例方法。
1、扩展方法的基本语法
扩展方法需要满足以下条件:
- 必须是 静态方法。
- 必须在 静态类 中定义。
- 第一个参数是要扩展的类型,且该参数前面需要加上
this关键字。
示例:
public static class StringExtensions
{// 扩展方法:为 string 类型添加 Log 方法public static void Log(this string str){Console.WriteLine($"打印:str");}
}
在上面的例子中,我们为 string 类型添加了一个 Log 方法,打印字符串。
2、使用扩展方法
定义了扩展方法后,可以像调用实例方法一样,直接通过扩展类型的实例调用它们。
class Program
{static void Main(){string str = "Hello, World!";str.Log();}
}
上面的代码中,我们通过 str.Log() 调用了 string 类型的扩展方法 Log,这看起来就像 string 类型原本就有这个方法一样。
结果

3、扩展方法的注意事项
-
命名空间:扩展方法必须在
using指令引入其定义所在的命名空间后才能使用。例如,假设StringExtensions类位于MyExtensions命名空间下,那么使用时需要引入该命名空间:using MyExtensions;// 然后可以直接使用扩展方法 -
静态方法:虽然扩展方法表现得像实例方法,但它们实际上是静态方法。编译器会将扩展方法的调用转换为相应的静态方法调用。
-
优先级:扩展方法的优先级通常高于实例方法,因此,如果某个类型已经实现了与扩展方法同名的方法,实例方法会优先被调用。
-
不可重写:扩展方法无法覆盖类型的现有方法。例如,如果你为
string类型扩展了一个Reverse方法,它不会覆盖string类型的原始方法或其他扩展方法。
5、扩展方法的限制
虽然扩展方法非常强大,但它们有一些局限性和注意事项:
- 无法访问私有成员:扩展方法只能访问公共和保护成员,不能访问目标类型的私有成员。
- 会导致命名冲突:如果多个扩展方法使用相同的名称并且作用于相同的类型,就可能引起命名冲突。可以通过限定命名空间来解决这种问题。
- 不支持扩展构造函数:扩展方法只能扩展已有的实例方法,不能添加构造函数、字段或事件。
6、总结
扩展方法是 C# 中非常有用的特性,能够通过增加新的方法而不修改现有类型的代码来增强功能。它们适用于添加一些工具方法、帮助函数等,特别是在不能直接修改类代码的情况下。
- 扩展方法定义在静态类中,并且需要使用
this关键字来标记目标类型。 - 使用扩展方法时,需要确保引入其定义所在的命名空间。
- 扩展方法虽然在语法上像实例方法,但其实是静态方法。
二、运算符重载
1、C# 运算符重载
在 C# 中,运算符重载允许你为自定义类型(类或结构体)定义特定的运算符行为。通过运算符重载,你可以使自定义类型像内建类型(例如 int 或 double)一样使用运算符进行操作。运算符重载是通过重写某些运算符的方法来实现的。
2、运算符重载的基本语法
运算符重载方法必须是 静态方法,并且需要使用关键字 operator 来定义。它的基本语法如下:
public static <返回类型> operator <运算符>(<类型1> 参数1, <类型2> 参数2)
{// 你的运算符实现逻辑
}
3. 示例:重载加法运算符 (+)
假设我们有一个表示二维坐标的 Point 类型,我们希望为其重载 + 运算符,使得两个 Point 对象可以相加。
public class Point
{public int X { get; set; }public int Y { get; set; }// 构造函数public Point(int x, int y){X = x;Y = y;}// 重载加法运算符 (+)public static Point operator +(Point p1, Point p2){return new Point(p1.X + p2.X, p1.Y + p2.Y);}
}
在这个例子中,+ 运算符被重载为将两个 Point 对象的 X 和 Y 坐标分别相加。
4、使用重载的运算符
重载运算符之后,你可以像操作内建类型一样操作 Point 类型:
public class Program
{public static void Main(){Point p1 = new Point(2, 3);Point p2 = new Point(5, 7);Point result = p1 + p2; // 使用重载的 + 运算符Console.WriteLine($"({result.X}, {result.Y})"); // 输出 (7, 10)}
}
在这里,p1 + p2 实际上调用了 Point 类型中定义的 operator + 方法,返回一个新的 Point 对象,X 和 Y 分别相加。
5、支持重载的运算符
- 算术运算符:
+,-,*,/,% - 关系运算符:
==,!=,<,>,<=,>= - 位运算符:
&,|,^,<<,>> - 单目运算符:
+(一元加),-(一元减),++,-- - 其他运算符:
[](索引器)、(),~(按位取反)、true,false,!(逻辑非)、is,as
6、不能重载的运算符
- 逻辑运算符:
&&,||
7、运算符重载的注意事项
-
必须是静态方法:运算符重载方法必须是静态的,因此无法访问实例成员(除非通过参数传入)。
-
返回值类型:运算符重载方法必须返回运算结果的类型。例如,
+运算符应返回加法结果,==运算符应返回一个bool类型的值。 -
重载
==和!=时需要保持一致性:如果你重载了==运算符,通常也需要重载!=运算符,以确保逻辑一致。 -
运算符的优先级和结合性不能改变:C# 不允许改变运算符的优先级或结合性。你只能指定运算符的行为,而无法改变它们的优先级。
-
建议只在必要时重载运算符:虽然运算符重载非常强大,但过多或不当的使用可能会导致代码的可读性变差。应该仅在自然语义上支持运算符操作时才重载它们。
8、总结
- 运算符重载是通过静态方法来实现的。
- 重载时应保持逻辑的一致性,尤其是
==和!=。 - 过度使用运算符重载可能会导致代码可读性降低,因此应适度使用。
三、内部类
内部类 是定义在另一个类或结构体内部的类。它通常用于实现封装,或者当一个类的功能仅在另一个类的上下文中有意义时,使用内部类可以增加代码的组织性和可维护性。内部类的访问权限可以是 public、private、protected 等,因此它可以根据需求暴露或隐藏给外部使用。
1、示例:
public class OuterClass
{// 外部类的字段private int outerField = 10;// 定义内部类public class InnerClass{// 内部类可以访问外部类的成员public void Display(){OuterClass outer = new OuterClass();Console.WriteLine("外部类的字段值: " + outer.outerField);}}
}class Program
{static void Main(){// 创建内部类的实例OuterClass.InnerClass inner = new OuterClass.InnerClass();inner.Display();}
}
2、特点:
- 内部类可以访问外部类的所有成员(包括私有成员)。
- 内部类可以作为外部类的一个组成部分,或者是外部类的一个辅助工具。
- 内部类的生命周期通常是由外部类来管理的。
四、partial 定义分部类
分部类 是指一个类的定义可以分散到多个文件中,这样有助于将一个庞大的类拆分成多个小的部分进行维护。partial 关键字用于声明类是分部类,编译器会在编译时将这些不同的部分合并成一个完整的类。
1、示例:
假设你有两个文件 Class1.Part1.cs 和 Class1.Part2.cs,它们都属于同一个类 Class1:
- Class1.Part1.cs:
public partial class Class1
{public void Method1(){Console.WriteLine("Method1 from Part1");}
}
- Class1.Part2.cs:
public partial class Class1
{public void Method2(){Console.WriteLine("Method2 from Part2");}
}
2、使用:
class Program
{static void Main(){Class1 obj = new Class1();obj.Method1(); // 来自 Part1obj.Method2(); // 来自 Part2}
}
3、特点:
- 分部类使得一个类可以被分布在多个文件中,这对于大型项目非常有用。
- 各个部分可以在不同的代码文件中定义,但它们会被视为同一个类。
partial类的不同部分可以放在不同的命名空间或文件中,只要它们在同一项目中即可。- 各个部分的访问修饰符、方法和属性都可以独立指定,但它们最终会被合并为一个类。
专栏推荐
| 地址 |
|---|
| 【从零开始入门unity游戏开发之——C#篇】 |
| 【从零开始入门unity游戏开发之——unity篇】 |
| 【制作100个Unity游戏】 |
| 【推荐100个unity插件】 |
| 【实现100个unity特效】 |
| 【unity框架开发】 |
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
好了,我是向宇,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关文章:
【从零开始入门unity游戏开发之——C#篇21】C#面向对象的封装——`this`扩展方法、运算符重载、内部类、`partial` 定义分部类
文章目录 一、this扩展方法1、扩展方法的基本语法2、使用扩展方法3、扩展方法的注意事项5、扩展方法的限制6、总结 二、运算符重载1、C# 运算符重载2、运算符重载的基本语法3. 示例:重载加法运算符 ()4、使用重载的运算符5、支持重载的运算符6、不能重载的运算符7、…...
Java进程占用的内存有哪些部分?
大家好,我是锋哥。今天分享关于【Java进程占用的内存有哪些部分?】面试题。希望对大家有帮助; Java进程占用的内存有哪些部分? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Java进程在运行时,会将内存划分为多个区域…...
【华为OD机试真题】【2024年E卷】数值同化-队列BFS(C++/Java/Python)
文章目录 分值:200题目描述思路复杂度分析AC 代码 分值:200 题目描述 存在一个 m * n 的 二维数组只,其成员取值范围为0, 1, 2。其中值为1的元素具备同化特性,每经过1S,将上下左右值为0的元素同化为1。而值为2的元素…...
“魔法糖果盒的秘密:用朴素贝叶斯算法猜糖果颜色”
想象一下,你有一个神奇的糖果盒,这个糖果盒里有两种糖果:红色的和蓝色的。你闭上眼睛,从盒子里拿出一个糖果,然后尝一尝,你想知道这个糖果是红色的还是蓝色的。朴素贝叶斯算法就像是一个魔法规则࿰…...
linux中docker命令大全
基本命令 docker pull 拉取镜像 docker pull docker push 推送镜像到DockerRegistry docker push docker images 查看本地镜像 docker images docker rmi 删除本地镜像 docker rmi docker run 创建并运行容器(不能重复创建) docker run d…...
Python `str.strip()` 的高级用法详解
Python str.strip 的高级用法详解 1. str.strip() 的基本用法2. str.strip() 的高级用法2.1 移除指定字符2.2 移除多个指定字符2.3 移除换行符和制表符2.4 结合正则表达式的高级处理 3. lstrip() 和 rstrip() 的用法3.1 lstrip():移除左端字符3.2 rstrip()ÿ…...
[蓝桥杯 2019 国 B] 排列数
目录 前言 题解 思路 疑问 解答 前言 对于本篇文章是站在别人的基础之上来写的,对于这道题作为2019年国赛B组的最难的一题,他的难度肯定是不小的,这道题我再一开始接触的时候连思路都没有,也是看了两三遍别人发的题解&#x…...
[bug] StarRocks borker load意向之外的bug
意向之外,又清理之中 背景: StarRocks各方面碾压相同类型的数据库,最近我们要从生成HIVE导历史数据(ORC格式)到StarRocks,前期小测一下,在测试是没问题,上生产先导2个月的数据&…...
2025年前端面试热门题目——HTML|CSS|Javascript|TS知识
以下是对这些 HTML 面试问题的详细解答: 1. HTML 的 src 和 href 属性有什么区别? src (Source) 属性: 用于嵌入资源,例如图像、脚本或 iframe。加载资源时,当前页面的加载会暂停,直到资源加载完成。常用于 <img&g…...
Linux中部署项目
1.下载JDK17 进入 /usr/local 目录,创建 java 文件夹。并将 JDK17 上传到 java 目录下。 上传成功后,通过cd命令进入Java文件夹目录,解压 JDK17 压缩包,命令 unzip zulu17.44.53-ca-jdk17.0.8.1-linux_x64.zip。 如果报错说 u…...
在 CentOS 上安装 MySQL 8
在 CentOS 上安装 MySQL 8 您可以按照以下步骤操作: 1. 更新系统 首先,更新系统软件包以确保安装的最新版本。 sudo yum update -y 2. 安装 MySQL 8 安装 MySQL 存储库 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.r…...
gradle项目下载依赖报错
报错信息 Cannot resolve external dependency org.projectlombok:lombok:1.18.36 because no repositories are defined. Required by:project :Possible solution:- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/…...
solon 集成 activemq-client (sdk)
原始状态的 activemq-client sdk 集成非常方便,也更适合定制。就是有些同学,可能对原始接口会比较陌生,会希望有个具体的示例。 <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-client&l…...
LRU 缓存
LRU 缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否…...
使用ZLMediaKit 开源项目搭建RTSP 服务器
ZLMediaKit 是啥? ZLMediaKit是国人开发的开源C流媒体服务器,同SRS一样是主流的流媒体服务器。 ZLToolKit是基于C11的高性能服务器框架,和ZLMediaKit是同一个作者,ZLMediaKit正是使用该框架开发的。 官网 ZLMediaKit开源地址&…...
数组晨考2day08
1.用一句话描述数组 在内存中 一块连续的空间 存储相同类型的数据 长度是固定的 2.数组各个类型的默认值 整数:0 浮点:0.0 布尔:false 字符:\u0000 其他:null 3.Arrays类toString,copyOf,sort&a…...
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》简介
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》已于近日上市,该书由北京大学出版社出版。距离第1版上市已经过去二年半多。本文希望与读者朋友们分享下这本书里面的大致内容。 封面部分 首先是介绍封面部分。 《鸿蒙HarmonyOS应用开发从入门…...
麒麟操作系统服务架构保姆级教程(二)sersync、lsync备份和NFS持久化存储
如果你想拥有你从未拥有过的东西,那么你必须去做你从未做过的事情 上篇文章我们说到rsync虽好,但是缺乏实时性,在实际应用中,咱们可以将rsync写进脚本,然后写进定时任务去备份,如果每天凌晨1:00…...
将OBJ或GLB文件转换为3DTiles
格式简介 GLB文件(.GLB)代表“GL传输格式二进制文件”,是用于共享3D数据的标准化文件格式。确切地说,它可以包含有关三维模型、场景、模型、光源、材质、节点层次和动画的信息。 OBJ文件是一种文本文件格式,这就意味…...
Flink DataStream API 编程指南
(对于Flink的开发,建议使用Java,Scala的支持未来会被移除) DataStream是什么 DataStream API得名于DataStream这个Java类,可以将它们视为可以包含重复项的不可变数据集合。该数据可以是有限的,也可以是无限的,用于处理它们的API是相同的。 DataStream在用法上和普通的…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
