C#中的隐式操作符,如何简化类型转换

🏆作者:科技、互联网行业优质创作者
🏆专注领域:.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造
🏆欢迎关注我(Net数字智慧化基地),里面有很多高价值技术文章,是你刻苦努力也积累不到的经验,能助你快速成长。升职+涨薪!!

C#中的隐式操作符:如何简化类型转换

摘录

学习如何通过使用 C# 中的隐式操作符执行隐式转换。这是一个有用的特性,如果小心使用,可以增强可读性。


C#中的隐式操作符允许我们定义在处理多种类型时发生的自定义类型转换——正如你所猜测到的那样——隐式进行。在这个场景中隐式意味着我们不必显式地进行类型转换,因为我们实现的隐式操作符会为我们处理这一切。

C#中的隐式操作符在简化数据类型转换中起到作用[1]。它们允许你无缝转换一种类型到另一种类型,而无需显式地转换值。这个功能可以节省你的时间和精力,并提高代码的可读性,但就像我们查看的所有事物一样,也有需要考虑的缺点。

在本文中,我们将探索 C# 中隐式操作符的使用案例[2]并检查代码示例来说明它们的实际应用。让我们深入了解 C# 中的隐式操作符吧!


什么是C#中的隐式操作符?

C#中的隐式操作符是一种强大的特性,允许一种类型的对象自动转换为另一种类型,而无需显式转换。它们提供了一种无缝转换类型的方法,使代码更加简洁和可读。

隐式操作符被定义为类或结构体中的特殊方法,使用implicit关键字。这些方法指定了从一种类型到另一种类型的转换。当编译器遇到涉及兼容类型的赋值或表达式时,它将自动调用适当的隐式操作符来执行转换。

以下是一个说明这个概念的示例:

public struct Celsius
{public Celsius(double value){Value = value;}public double Value { get; }// 从 Celsius 到 Fahrenheit 定义一个隐式操作符public static implicit operator Fahrenheit(Celsius celsius){double fahrenheit = celsius.Value * 9 / 5 + 32;return new Fahrenheit(fahrenheit);}
}public struct Fahrenheit
{public Fahrenheit(double value){Value = value;}public double Value { get; }
}public class Program
{public static void Main(){// 隐式将一个 Celsius 温度转换为 FahrenheitCelsius celsius = new Celsius(25);Fahrenheit fahrenheit = celsius;Console.WriteLine(fahrenheit.Value);  // 输出:77}
}

在这个例子中,我们有一个带有Value属性的Celsius类型。我们在Celsius类型中定义了一个隐式操作符,它将一个Celsius值转换为Fahrenheit。当我们将一个Celsius值赋给一个Fahrenheit变量时,编译器自动调用隐式操作符,将温度从摄氏度转换为华氏度。

C#中的隐式操作符可以通过允许对象在适当时自动转换来大大简化代码。这可以使代码更易于阅读,并减少显式类型转换的需要。然而,重要的是要谨慎使用隐式操作符,并确保转换是安全和逻辑上合理的。


隐式操作符在C#中的优缺点

就像我们看到的一切一样,总会有优点和缺点。我试图确保我们在我的网站和我的 YouTube 频道[3]上共同讨论的每个话题都观察多个视角。在我看来,这是理解事物是更好还是更差配合的最佳方式。

隐式操作符在C#中的优点

C#中的隐式操作符在软件开发中提供了几个好处。它们可以通过允许自动类型转换而不需要显式转换或转换方法来简化代码和提高可读性。这消除了重复和可能错误的代码的需要,使代码库更加简洁易懂。

考虑以下示例,我们有一个自定义类型Length,表示我们正在处理的测量单位:

public struct Length
{public double Value { get; set; }// 从 Length 到 double 的隐式转换public static implicit operator double(Length length){return length.Value;}
}

通过定义隐式操作符,我们可以在计算中使用这个自定义类型,而不需要显式地将它们转换为其底层类型:

Length length = new Length { Value = 5.0 };
double finalResult = (length * 1.23) / 42d;
Console.WriteLine($"答案是 {finalResult}.");

需要注意的一点是,几乎任何具有这样值的数量都需要指示测量单位——这在这个示例中被省略了,因为你可以通过多种方式做到这一点,我不希望这成为焦点。因此,在这个示例中有一个假设,我们确实知道我们在处理哪个单位。

我们添加的操作符的隐式转换使代码更简单,通过减少显式转换的次数并通过更清晰地表达意图来提高可读性。如果我们需要在数学声明中到处添加(double)和其他转换,它开始分散对表达式本身的理解。

隐式操作符在C#中的缺点

隐式操作符的一个大缺点与我们之前看到的一个优点非常相关。我们可以隐式转换的事实可能会导致我们在不小心时进入非常奇怪的情形。

我们引入另一种也可以隐式转换为double的自定义类型。我们可以像之前一样假设我们知道这个表示数量的类型的单位。下面是代码,与前一个类型非常相似:

public struct Temperature
{public double Value { get; set; }// 从 Temperature 到 double 的隐式转换public static implicit operator double(Temperature temperature){return temperature.Value;}
}

由于两种类型都可以隐式转换为double,我们有能力写出这样的数学表达式而不需要转换——但我们应该这么做吗?

Length length = new Length { Value = 5.0 };
Temperature temperature = new Temperature { Value = 25.0 };
double finalResult = ((length * temperature) + 42d) / 1.23;
Console.WriteLine($"答案是 {finalResult}.");

在这个示例中,隐式操作符允许直接执行LengthTemperature对象之间的乘法,而不需要显式转换。从隔离的角度来看,可能允许任一类型转换为double是有意义的,但当它们都可以转换时,结果可能是意外的。

举个例子,如果你的长度是米,将它们转换为一个称为lengthInMeters的double并不是太难。但是double本身是无单位的,当我们开始通过混合其他类型来累积这一点时,跟踪我们实际上在谈论什么单位的负担开始超过隐式转换的好处。在我看来,如果我们被迫显式转换并在必要时跟踪中间步骤中的转换,会更易于阅读。

这当然只是一个例子,但重点是,如果你在隐式转换中可能丢失数据分辨率(在这种情况下是单位),那么你就冒着这种风险。除了可能其他开发人员在pull请求和代码审查中阻止我们外,没有什么能阻止我们作为C#开发人员这么做!


隐式操作符的使用案例

在这一部分,我将展示三个C#中隐式操作符的实际使用案例。隐式操作符是一种强大的特性,允许不同类型之间的自动转换。理解和利用隐式操作符可以极大地简化你的代码并提高其可读性。让我们探索三个隐式操作符在C#中可以有用的使用案例。

转换自定义类型 - 心系金钱

隐式操作符的一个主要使用案例是转换自定义类型。假设我们有一个自定义类型Money,代表某种货币的金额。我们可能希望允许Money隐式转换为double,以简化计算并启用直接比较。以下是我们如何定义隐式操作符来实现这一点:

public struct Money
{private readonly double _amount;public Money(double amount){_amount = amount;}public double Amount => _amount;// 将 Money 隐式转换为 doublepublic static implicit operator double(Money money){return money._amount;}// 将 double 隐式转换为 Moneypublic static implicit operator Money(double amount){return new Money(amount);}
}// 用法
class Program
{static void Main(string[] args){Money moneyInWallet = new Money(100.50); // $100.50double cash = moneyInWallet; // 向 double 的隐式转换// 增加更多的钱moneyInWallet += 99.50; // 从 double 到 Money 的隐式转换,然后加法Console.WriteLine(cash); // 输出:100.5Console.WriteLine(moneyInWallet.Amount); // 输出:200}
}

通过定义从Moneydouble的隐式转换操作符,我们现在可以直接将一个Money对象赋值给一个double变量,而不需要显式类型转换。如果你想要拥有更具表现力的财务计算,通过拥有Money类型,这可能是有用的,而不是强制到处转换操作。

简化数学运算

隐式操作符还可以通过自动将操作数转换为兼容类型来简化数学运算。假设我们有一个代表复数的类型ComplexNumber,我们希望对它们执行算术运算。通过使用隐式操作符,我们可以在执行数学运算时无缝地将整数和double转换为ComplexNumber。在这种情况下,我们不仅需要隐式操作符进行转换,还需要操作符在两个ComplexNumber实例之间进行算术。

这是一个示例:

public class ComplexNumber
{public double Real { get; set; }public double Imaginary { get; set; }public ComplexNumber(double real, double imaginary){Real = real;Imaginary = imaginary;}// 将 int 隐式转换为 ComplexNumberpublic static implicit operator ComplexNumber(int number){return new ComplexNumber(number, 0);}// 将 double 隐式转换为 ComplexNumberpublic static implicit operator ComplexNumber(double number){return new ComplexNumber(number, 0);}// 添加两个 ComplexNumber 实例public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b){return new ComplexNumber(a.Real + b.Real, a.Imaginary + b.Imaginary);}
}// 用法
ComplexNumber complexNumber = 2.5; // 从 double 的隐式转换
complexNumber += 3; // 从 int 的隐式转换
Console.WriteLine(complexNumber.Real); // 输出:5.5

有了隐式操作符,我们可以在不需要显式转换的情况下,在ComplexNumber对象上使用整数或双精度数执行数学运算。如果你正在创建一个应用程序,其中包含了很多与这些概念的算术运算,你可能会发现,不必经常转换可以提高代码的可读性。

与其他库的转换:一个几何示例

当与具有代表相似概念的不同类型的库或API一起工作时,隐式操作符可能特别有用。通过在这些类型之间创建隐式操作符,你可以无缝地在它们之间转换并简化与库的交互。

例如,考虑我们想要创建的一个库,该库提供了不同类型来表示二维空间中的点。该库可能定义了Point2DVector2D类型,每种类型都有自己的一套操作。通过在这些类型之间定义隐式操作符,你可以使用户能够根据代码的需要,使用不同的对象来表示不同的概念,从而轻松地在Point2DVector2D对象之间转换:

public struct Point2D
{// 从 Point2D 到 Vector2D 的隐式转换public static implicit operator Vector2D(Point2D point){return new Vector2D(point.X, point.Y);}
}public struct Vector2D
{// 从 Vector2D 到 Point2D 的隐式转换public static implicit operator Point2D(Vector2D vector){return new Point2D(vector.X, vector.Y);}
}

有了这些隐式操作符,用户可以无缝地在Point2DVector2D对象之间转换,根据其代码的需要使用它们:

Point2D point = new Point2D(2, 3);
Vector2D vector = new Vector2D(4, 5);// 从 Point2D 到 Vector2D 的隐式转换
Vector2D convertedVector = point;// 从 Vector2D 到 Point2D 的隐式转换
Point2D convertedPoint = vector;

在这种场景下,隐式操作符通过允许用户使用不同的对象代表不同的概念来处理相同的底层数据,简化了代码并使其更具表达性。在我们想要将第三方库整合进我们的代码库,并希望在与之交互时提供一定级别的灵活性的类似情况下,可能会有好处。对于我们拥有的类型,我们可以为所涉及的库提供隐式转换,这可能会简化我们在与库交互时代码库中的逻辑。


频繁问到的问题:C#中的隐式操作符

C#中的隐式操作符是什么?

C#中的隐式操作符是一种特殊方法,允许在两种类型之间自动转换,无需显式强制类型转换。它们使用implicit关键字定义,并启用隐式类型转换。

为什么在C#开发中隐式操作符很重要?

理解并使用C#中的隐式操作符可以帮助软件工程师通过简化类型转换编写更清晰、更可读的代码。它们提供了一种方便的方式来处理类型转换,而无需显式强制类型转换,导致代码更简洁、易于维护。

C#中的隐式操作符如何工作?

在两种类型之间定义了隐式操作符时,编译器会在需要隐式类型转换时自动调用它。操作符无缝地将一个类型的实例转换为另一个类型,如果转换有效的话。编译器在赋值和方法参数中检测和应用隐式操作符,简化了代码并使其更直观。

使用C#中的隐式操作符有什么好处?

使用隐式操作符可以提升代码可读性,简化类型转换,并减少对显式强制类型转换的需求。它们可以通过消除不必要的类型转换代码使代码更加简洁,改善代码可维护性并减少强制类型转换错误的机会。当然,过度使用这个功能,创建在特定上下文之外可能没有意义的转换,或可能丢失数据精度,也是很容易发生的。

C#中隐式操作符的一些用例是什么?

隐式操作符通常用于转换具有自然关系或可以逻辑地解释为彼此的类型。一些常见的用例包括自定义类之间的转换、具有安全范围约束的数字类型之间的转换,以及简化从一种数据结构到另一种数据结构的转换。

🏆欢迎关注我(Net数字智慧化基地),里面有很多高价值技术文章,是你刻苦努力也积累不到的经验,能助你升职+涨薪!!
🏆点击下方卡片关注公众号,里面有很多大佬的技术文章,能助你快速成长。还可免费领取如下15个视频教程!

回复'面试',获取C#/.NET/.NET Core面试宝典

回复'C#',领取零基础学习C#编程

回复'NET',领取.NET零基础入门到实战

回复'Linux',领取Linux从入门到精通

回复'wpf',领取高薪热门【WPF上位机+工业互联网】从零手写实战

回复'Modbus',领取初识C#+上位机Modbus通信

回复'PLC',领取C#语言与西门子PLC的通信实操

回复'blazor',领取blazor从入门到实战

回复'TypeScript',领取前端热门TypeScript系统教程

回复'vue',领取vue前端从入门到精通

回复'23P',领取C#实现23种常见设计模式

回复'MongoDB',领取MongoDB实战

回复'Trans',领取分布式事务

回复'Lock',领取分布式锁实践

回复'Docker',领取微服务+Docker综合实战

回复'K8s',领取K8s部署微服务

回复'加群',进.NET技术社区交流群 

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

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

相关文章

RocketMQ学习笔记四(黑马)项目

课程地址: 1.Rocket第二章内容介绍_哔哩哔哩_bilibili (视频35~88,搭建了一个电商项目) 待学,待完善。

JVM相关

文章目录 JVM的类加载过程JAVA内存泄露内存泄露的常见原因内存泄露的影响问题排查 JVM的调优java四种引用类型 JVM的类加载过程 JVM的类加载过程包括加载(Loading)、验证(Verification)、准备(Preparation&#xff09…

找准方向选CRM客户管理系统!2023年排行榜推荐

本文将为大家带来2023有哪些好用CRM客户管理系统?CRM系统排行榜基于品牌知名度、功能、产品实力、系统稳定性、用户体量等多重因素考量。其中Zoho CRM、红圈CRM等产品市场表现优异入选此次榜单。 1.Zoho CRM 公司成立时间:1996年 Zoho(卓豪…

【算法】AC自动机的优化:增量更新与删除

一、概述 AC自动机(Aho-Corasick Automation)是著名的多模匹配算法,源于贝尔实验室,并且在实际应用中得到广泛的引用,且具有以下特点: 只需要扫描一次文本,即可获取所有匹配该文本的模式串复杂…

CSS扩展选择器

文章目录 1. 并集选择器2. 交集选择器3. 后代选择器4. 子代选择器5. 兄弟选择器5.1. 相邻兄弟选择器5.2. 通用兄弟选择器 6. 属性选择器7. 伪类选择器7.1. 动态伪类7.2. 结构伪类7.3. 否定伪类 8. 伪元素选择器9. Google 改进案例 1. 并集选择器 选中多个选择器对应的元素。一…

如何在Linux上使用git远程上传至gitee托管(add-commit-push指令详解)

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

力扣209. 长度最小的子数组

思路:题目是 数组和 > target,不是等于target 双指针法:用for循环中的 r 来界定右边界的下标,右边界每移动一位,左边界可能需要移动多位,所以内部再用while, 当满足 数组和>target时,记录…

C语言基础之结构体

文章目录 一、结构体1、结构体概述2、结构体类型的定义方式(1)先定义结构体类型,再定义结构体变量(2)结构体类型、变量同时定义(3)一次性结构体 3、结构体成员的初始化(1)结构体初始化(2)清空结…

Flutter 添加三方库后,运行不起来或缓慢问题(Gradle)

背景 在Flutter项目(包含Android平台)初期,经常发现在Flutter添加了一个三方库依赖之后,重新运行的时候就要等很久,或者直接报错。查看详细日志会发现,耗时一般都是由于新的三方库也有自己的Android的代码…

RISC-V Optimization Guide(笔记)

官网发表的文章地址:RISC-V Optimization Guide B站有人做过解读视频,这篇文章也是看视频时做的笔记:视频地址 一、标量整数优化 1.1 常量的具体化 使用lui/addiw将立即数加载至寄存器,当立即数低12位的最高位为1时&#xff0c…

数据库 | MYSQL这个复杂系统如何上手?

当你不知道从何入手研究或解决一个复杂系统的问题时,通常意味着你没有找到合适的切入点或者缺乏对系统整体和细节之间联系的理解。在这种情况下,一个有用的策略是寻找系统的基本原理或构成要素。 小时候,你可能也玩过玩具四驱车。有的四驱车…

Elasticsearch(10) match的使用

elasticsearch version&#xff1a; 7.10.1 Elastic Match是Elasticsearch中用于全文搜索的一种查询语法。它可以将搜索词进行分词&#xff0c;并与目标查询字段进行匹配。 match的语法 GET /<index>/_search {"query": {"match": {"<fiel…

从零开始利用MATLAB进行FPGA设计(三)将Simulink模型转化为定点数据类型

文章灵感来源于MATLAB官方免费教程&#xff1a;HDL Coder Self-Guided Tutorial 考虑到MATLAB官网的英文看着慢&#xff0c;再加上视频讲解老印浓浓的咖喱味&#xff0c;我决定记录利用MATLAB&Simulink&SystemGenerator进行FPGA数字信号处理的学习过程。 往期回顾&am…

Alias许可数量计算

在数字化时代&#xff0c;软件许可数量的合理配置是企业实现成本控制与合规运营的关键。然而&#xff0c;企业在计算软件许可数量时&#xff0c;往往面临诸多困惑。如何精确评估软件需求&#xff0c;确保合规使用&#xff0c;降低成本&#xff0c;成为了企业关注的焦点。Alias许…

grep和vim查找日志文件信息

grep和vim查找日志文件信息 前言&#xff1a;最近排查问题时&#xff0c;经常用到grep和vim查找日志&#xff0c;记录下。 #1、在当前目录下查询文件中是否包含&#xff1a;test内容 $grep -nr test #2、vim查看日志 #2.1、vim文件后&#xff0c;用大写GG&#xff0c;快速…

什么是响应式设计?响应式设计的基本原理是什么?如何做?

文章目录 一、是什么二、实现方式媒体查询百分比vw/vhrem小结 三、总结参考文献 一、是什么 响应式网站设计&#xff08;Responsive Web design&#xff09;是一种网络页面设计布局&#xff0c;页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)…

前端图片预加载和懒加载

前言 在说到对图片资源进行优化时&#xff0c;那就不得不提到图片预加载和图片懒加载&#xff0c;可能很多朋友都了解这两者&#xff0c;但是一直没有很清晰的概念&#xff0c;以及什么时候用&#xff0c;用在什么场景下&#xff0c;今天就来详细的了解一下吧&#xff01; 图…

软考高级:BPR 和 BPM概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

【四 (1)数据可视化之如何选用正确的图表】

目录 文章导航一、数据分析中可视化的作用1、揭示数据关联和模式2、支持数据分析和决策3、提升沟通和共享效果4、强调关键信息和发现5、增强故事叙述和记忆效果6、有效增强数据交互性数据7、复杂信息易理解8、数据多维度显示 二、如何选用合适的图表1、简洁性避免使用过于复杂或…

软考高级:企业应用集成概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…