C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法

目录

一、什么是拓展方法?

二、拓展方法有啥用?怎么写拓展方法?

1. ​核心用途

2. ​编写步骤

实现步骤

关键点说明

关键规则

3. ​注意事项

三、什么是运算符重载?

四、运算符重载有啥用?怎么写?

1. ​核心用途

2. ​编写步骤

3. ​可重载的运算符

4. ​注意事项

五、总结

​对比表:拓展方法 vs 运算符重载


前言:当代码学会“七十二变”​

        有没有想过,让 string 类型突然学会统计单词数?或者让你的自定义类像 int 一样支持加减乘除?

        C#的拓展方法就像“魔法外挂”,能让任何类型瞬间解锁新技能,而运算符重载则是“对象变身术”,让你的类摇身一变成为数学高手!

本文将揭秘这两个神器的使用秘籍,让你告别冗长代码,拥抱优雅语法——从此,你的代码不仅能“说话”,还能“算卦”!

一、什么是拓展方法?

        拓展方法(Extension Methods)​是C#中一种特殊的语法,允许为现有类型(包括密封类或系统类型)添加新方法,而无需修改原始代码或创建子类。

概念
为现有的 非静态变量 添加 新方法
作用
1.提高程序拓展性
2.不需要在对象中重新写方法
3.不需要继承来添加方法
4.为别人封装的类型写额外的方法
特点
1.一定是写在静态类中
2.一定是个静态函数
3.第一个参数为拓展目标
4.第一个参数用this修饰

  • 核心特点
    • 定义在静态类中,方法为静态方法。
    • 第一个参数用 this 关键字修饰,表示要扩展的类型。
    • 扩展方法的本质是一个静态方法,但在调用时,编译器会自动将实例对象(即调用者)​作为第一个参数传递进去。这种语法糖让扩展方法看起来像是实例方法,但实际上背后是静态方法的调用逻辑。

基本语法:访问修饰符 static 返回值 函数名(this 拓展类名 参数名,参数类型 参数名,)

  • 示例:为 string 类型添加一个统计单词数的方法。
public static class StringExtensions {public static int WordCount(this string str) {return str.Split(new[] {' ', '.', '?'}, StringSplitOptions.RemoveEmptyEntries).Length;}
}// 使用
string text = "Hello, how are you?";
Console.WriteLine(text.WordCount()); // 输出 4

二、拓展方法有啥用?怎么写拓展方法?

1. ​核心用途

  • 扩展现有类型功能:尤其适用于无法修改源码的类(如系统类型或第三方库)。
  • 链式调用:让代码更流畅(如LINQ基于拓展方法实现)。
var numbers = new List<int> { 1, 2, 3 };
var sum = numbers.Where(n => n > 1).Sum(); // LINQ的Where和Sum均为拓展方法

2. ​编写步骤

  1. 创建静态类:类名建议以 Extensions 结尾(如 StringExtensions)。
  2. 定义静态方法:第一个参数用 this 修饰,表示目标类型。

基本语法:访问修饰符 static 返回值 函数名(this 拓展类名 参数名,参数类型 参数名,)

    public static class MathExtensions {public static double Square(this int num) => num * num;
    }
    // 使用
    int num = 5;
    Console.WriteLine(num.Square()); // 25

            除了为系统内部的类型进行拓展方法,我们自己还可以为自己写的静态类进行拓展方法:      假设有一个 Product 类,表示商品信息:

    实现步骤
    1. 定义静态类:创建名为 ProductExtensions 的静态类。
    2. 编写扩展方法:添加一个静态方法,第一个参数用 this Product product 修饰。
    3. 实现逻辑:在方法内部访问 Product 的公开属性。
    public class Product {public string Name { get; set; }public decimal Price { get; set; }public int Stock { get; set; }
    }

            我们希望为 Product 添加一个扩展方法,用于生成商品描述的格式化字符串,而无需修改 Product 类的原始代码。就可以如下书写:

    public static class ProductExtensions {// 扩展方法:生成商品描述public static string GetDescription(this Product product) {return $"{product.Name} - 价格:¥{product.Price},库存:{product.Stock}件";}// 扩展方法:检查库存是否充足public static bool IsInStock(this Product product, int requiredQuantity) {return product.Stock >= requiredQuantity;}
    }

    测试:

    // 创建商品实例
    var product = new Product {Name = "无线蓝牙耳机",Price = 299.99m,Stock = 50
    };// 调用扩展方法
    string description = product.GetDescription();
    bool isAvailable = product.IsInStock(30);Console.WriteLine(description); 
    // 输出:无线蓝牙耳机 - 价格:¥299.99,库存:50件
    Console.WriteLine(isAvailable ? "库存充足" : "库存不足"); 
    // 输出:库存充足

    关键点说明

    1. ​静态类与静态方法:

      • 所有扩展方法必须定义在 static class 中。
      • 方法本身必须是 static 的,且第一个参数用 this 关键字标记目标类型。
    2. ​访问权限:

      • 扩展方法只能访问目标类型的 ​**public 成员**​(如 Product 的 NamePrice)。
      • 无法访问 private 或 protected 成员。
    3. ​命名空间依赖:

      • 若扩展方法定义在命名空间 MyExtensions 中,使用时需通过 using MyExtensions; 引入。 

    关键规则

    1. 隐式传递实例

      • 调用扩展方法时,实例对象(如 product)会自动成为静态方法的第一个参数。
      • 你无需(也不能)手动传递该参数。
    2. 附加参数

      • 扩展方法定义中除第一个参数(this参数)外的其他参数,需在调用时显式传入。
      • 例如 IsInStock(30) 中的 30 对应方法定义中的 requiredQuantity

    补充示例:为系统自带类int拓展的方法:

    public static class IntExtensions {// 判断数字是否为偶数public static bool IsEven(this int number) {return number % 2 == 0;}// 计算数字的平方public static int Square(this int number) {return number * number;}
    }// 使用
    int num = 5;
    Console.WriteLine(num.IsEven()); // 输出 False
    Console.WriteLine(num.Square()); // 输出 25

    3. ​注意事项

    • 拓展方法优先级低于类的实例方法。        
    • 无法访问类型的私有成员。
    • 需通过命名空间引入拓展方法所在的类。

    三、什么是运算符重载?

            运算符重载(Operator Overloading)​允许为自定义类型重新定义运算符的行为​(如 +==> 等)。

    概念
    让自定义的类和结构体
    能够运用运算符 

    使用关键字
    operator

    特点
    1.一定是一个公共的静态方法
    2.返回值写在operator前
    3.逻辑处理自定义

    作用
    让自定义类和结构体对象可以进行运算
    注意
    1.条件运算符需要成对出现
    2.一个符号可以多次重载
    3.不能使用ref out 

    • 核心规则
      • 使用 operator 关键字定义。
      • 必须是 public static 方法。
    • 示例:为自定义的 Vector 类重载 + 运算符。
    • 语法:public static 返回类型 operator 运算符(参数列表)
    public class Vector {public int X { get; }public int Y { get; }public Vector(int x, int y) { X = x; Y = y; }public static Vector operator +(Vector a, Vector b) {return new Vector(a.X + b.X, a.Y + b.Y);}
    }// 使用
    Vector v1 = new Vector(1, 2);
    Vector v2 = new Vector(3, 4);
    Vector sum = v1 + v2; // sum.X=4, sum.Y=6

    四、运算符重载有啥用?怎么写?

    1. ​核心用途

    • 自然语义:让自定义类型支持直观的运算符操作(如复数相加、矩阵乘法)。
    • 提高可读性:用 a + b 替代 a.Add(b)

    2. ​编写步骤

    1. 定义运算符方法:指定运算符和操作数类型。
    2. 实现运算逻辑:返回计算结果

    语法:public static 返回类型 operator 运算符(参数列表)

    如下是一个用来计算温度的  “  + ”:

    public class Temperature {public double Celsius { get; }public Temperature(double celsius) { Celsius = celsius; }public static Temperature operator +(Temperature t1, Temperature t2) {return new Temperature(t1.Celsius + t2.Celsius);}
    }

    3. ​可重载的运算符

    运算符类型示例
    算术运算符+-*/%
    比较运算符==!=><>=<=
    转换运算符implicit 或 explicit

    4. ​注意事项

    • 必须成对重载(如重载 == 必须同时重载 !=)。
    • 不能重载赋值运算符(如 =+=)。
    • 避免过度使用导致逻辑混乱(如让 + 执行减法操作)。

    五、总结

    对比表:拓展方法 vs 运算符重载

    特性拓展方法运算符重载
    核心目的扩展现有类型的功能自定义类型支持运算符操作
    语法要求静态类 + this 参数public static operator
    适用场景工具方法、链式调用、LINQ数学运算、集合操作、语义化操作
    限制无法访问私有成员需成对重载、不能重载所有运算符

    一句话记忆

    • 拓展方法:“别人家的孩子,我来教他新技能。”
    • 运算符重载:“我的对象,加减乘除我说了算!”

    掌握这两个特性,让你的C#代码像自然语言一样直观!

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

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

    相关文章

    银行卡归属地查询API接口如何对接?

    银行卡归属地查询 API 接口是一种能让开发者通过编程方式获取银行卡归属地等相关信息的工具。借助此接口&#xff0c;开发者可将银行卡归属地查询功能集成到自己的应用程序或系统里&#xff0c;像电商平台、第三方支付公司等都能运用它来提升业务的准确性与安全性。 银行卡归属…

    ORM mybits mybits-plus

    ORM ORM 即对象关系映射&#xff08;Object Relational Mapping&#xff09;&#xff0c;是一种程序设计技术&#xff0c;用于实现面向对象编程语言里不同类型系统的数据之间的转换。下面从基本概念、工作原理、优势与劣势、常见的 ORM 框架等方面详细介绍 ORM。 常见的orm框架…

    网络编程—网络概念

    目录 1 网络分类 1.1 局域网 1.2 广域网 2 常见网络概念 2.1 交换机 2.2 路由器 2.3 集线器 2.4 IP地址 2.5 端口号 2.6 协议 3 网络协议模型 3.1 OSI七层模型 3.2 TCP/IP五层模型 3.3 每层中常见的协议和作用 3.3.1 应用层 3.3.2 传输层 3.3.3 网络层 3.3.4…

    4月3日工作日志

    一个朴实无华的目录 今日学习内容&#xff1a;1.关系数据库 今日学习内容&#xff1a; 1.关系数据库

    git commit Message 插件解释说明

    - feat - 一项新功能 - fix - 一个错误修复 - docs - 仅文档更改 - style - 不影响代码含义的更改&#xff08;空白、格式化、缺少分号等&#xff09; - refactor - 既不修复错误也不添加功能的代码更改 - perf - 提高性能的代码更改 - build - 影响构建系统或外部依赖项…

    ngx_open_file

    定义在 src\os\unix\ngx_files.h #define ngx_open_file(name, mode, create, access) \open((const char *) name, mode|create, access) name&#xff1a;文件名&#xff08;通常是一个字符串&#xff09;。mode&#xff1a;文件打开模式&#x…

    23种设计模式-行为型模式-责任链

    文章目录 简介问题解决代码核心改进点&#xff1a; 总结 简介 责任链是一种行为设计模式&#xff0c;允许你把请求沿着处理者链进行发送。收到请求后&#xff0c;每个处理者均可对请求进行处理&#xff0c;或将其传递给链上的下个处理者。 问题 假如你正在开发一个订单系统。…

    注意力机制在大语言模型中的原理与实现总结

    注意力机制在大语言模型中的原理与实现总结 1. 章节介绍 在大语言模型的学习中&#xff0c;理解注意力机制至关重要。本章节旨在深入剖析注意力机制的原理及其在大语言模型中的应用&#xff0c;为构建和优化大语言模型提供理论与实践基础。通过回顾神经网络基础及传统架构的局…

    kafka消息可靠性传输语义

    Kafka提供了多种消息传递语义&#xff0c;以适应不同的业务需求和可靠性要求。以下是Kafka消息传输的可靠性语义及其实现机制&#xff1a; 1. At Most Once&#xff08;至多一次&#xff09; 语义&#xff1a;消息可能会丢失&#xff0c;但不会被重复传递。 实现机制&#xf…

    NLP高频面试题(三十三)——Vision Transformer(ViT)模型架构介绍

    Transformer架构在自然语言处理领域取得了显著成功&#xff0c;激发了研究人员将其应用于计算机视觉任务的兴趣。Vision Transformer&#xff08;ViT&#xff09;应运而生&#xff0c;成为图像分类等视觉任务中的新兴架构。本文将介绍ViT的基本架构、工作原理&#xff0c;并与传…

    Oracle数据库数据编程SQL<3.6 PL/SQL 包(Package)>

    包是Oracle数据库中一种重要的PL/SQL程序结构,它将逻辑相关的变量、常量、游标、异常、过程和函数组织在一起,提供了更好的封装性和模块化。在大型项目中,可能有很多模块,而每一个模块又有自己的存过、函数等。而这些存过、函数默认是放在一起的,如果所有的存过函数都是放…

    机器学习 分类算法

    【实验名称】 实验&#xff1a;分类算法 【实验目的】 1.了解分类算法理论基础 2.平台实现算法 3. 编程实现分类算法 【实验原理】 分类(Categorization or Classification)就是按照某种标准给对象贴标签(label),再根据标签来区分归类。 【实验环境】 OS&#xff1a;Ubuntu16.0…

    HTML5 Canvas绘画板项目实战:打造一个功能丰富的在线画板

    HTML5 Canvas绘画板项目实战&#xff1a;打造一个功能丰富的在线画板 这里写目录标题 HTML5 Canvas绘画板项目实战&#xff1a;打造一个功能丰富的在线画板项目介绍技术栈核心功能实现1. 画板初始化与工具管理2. 多样化绘画工具3. 事件处理机制 技术要点分析1. Canvas上下文优化…

    【YOLOv8】YOLOv8改进系列(12)----替换主干网络之StarNet

    主页&#xff1a;HABUO&#x1f341;主页&#xff1a;HABUO &#x1f341;YOLOv8入门改进专栏&#x1f341; &#x1f341;如果再也不能见到你&#xff0c;祝你早安&#xff0c;午安&#xff0c;晚安&#x1f341; 【YOLOv8改进系列】&#xff1a; YOLOv8结构解读 YOLOv8…

    1Panel 面板 宝塔面板 Ubuntu 24.04

    1Panel 面板 宝塔面板 Ubuntu 24.04 https://1panel.cn/ 1Panel 是一款开源的 Linux 服务器运维管理面板&#xff0c;它就像是给服务器配上了一个智能管家&#xff0c;让我们能通过 Web 端轻松管理服务器。以往我们管理 Linux 服务器&#xff0c;常常需要在命令行中输入各种复…

    Node.js全局生效的中间件

    目录 1. 目录结构 2. 代码实现 2.1 安装Express 2.2 app.js - 主文件 2.3 globalMiddleware.js - 全局中间件 3. 程序运行结果 4. 总结 在Node.js的Express框架中&#xff0c;全局生效的中间件是指应用程序启动后&#xff0c;对所有请求都有效的中间件。它通常用于日志记…

    WiFi(无线局域网)技术的多种工作模式

    WiFi&#xff08;无线局域网&#xff09;技术支持多种工作模式&#xff0c;以满足不同的网络需求和应用场景。以下是主要的WiFi工作模式及其详细说明&#xff1a; 1. 基础设施模式&#xff08;Infrastructure Mode&#xff09; [无线接入点 (AP)]/ | \ [客户端…

    PHP 8.x:现代Web开发的性能与效率革命

    随着PHP 8.x系列的持续演进&#xff0c;这门诞生于1995年的“古老”语言正焕发新生。通过引入革命性的JIT编译器、类型系统增强及一系列现代化语法特性&#xff0c;PHP 8.x不仅巩固了其在Web开发领域的统治地位&#xff0c;更将性能与开发者体验推向新高度。 一、JIT编译器&am…

    【扣子agent入门】搭建计算热量工作流

    一、食物热量知识库 1. 创建知识库 工作空间——资源库——创建资源>知识库 2. 自动采集网页数据 文本格式>在线数据 自动采集 找一个食物热量网站进行采集。 一定要让知识按条数分段&#xff0c;不然不好查询。 二、 意图识别节点 意图识别&#xff08;In…

    脑影像分析软件推荐 | JuSpace

    目录 1. 软件界面 2.工具包功能简介 3.软件安装注意事项 参考文献&#xff1a; Dukart J, Holiga S, Rullmann M, Lanzenberger R, Hawkins PCT, Mehta MA, Hesse S, Barthel H, Sabri O, Jech R, Eickhoff SB. JuSpace: A tool for spatial correlation analyses of magne…