时间:2021-05-20
前言
今天在研究公司项目框架的时候看到了下面的用法,public static implicit operator JsonData(int data); 。貌似很久没用过这种隐式转换的写法了,因此重新温习一下C#中转换相关的知识。
explicit 和 implicit 属于转换运算符,如用这两者可以让我们自定义的类型支持相互交换
explicti 表示显式转换,如从 A -> B 必须进行强制类型转换(B = (B)A)
implicit 表示隐式转换,如从 B -> A 只需直接赋值(A = B)
implicit
implicit 关键字用于声明隐式的用户自定义的类型转换运算符。 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。
使用隐式转换操作符之后,在编译时会跳过异常检查,所以隐式转换运算符应当从不引发异常并且从不丢失信息,否则在运行时会出现一些意想不到的问题。
示例
隐式转换可以通过消除不必要的强制转换来提高源代码的可读性。 但是,因为隐式转换不需要程序员将一种类型显式强制转换为另一种类型,所以使用隐式转换时必须格外小心,以免出现意外结果。 一般情况下,隐式转换运算符应当从不引发异常并且从不丢失信息,以便可以在程序员不知晓的情况下安全使用它们。 如果转换运算符不能满足那些条件,则应将其标记为 explicit。 有关详细信息,请参阅使用转换运算符。
explicit显示转换
explicit 关键字声明必须通过显示的调用用户定义的类型转换运算符来进行转换。
以下示例定义从 Fahrenheit 类转换为 Celsius 类的运算符。 必须在 Fahrenheit 类或 Celsius 类中定义运算符:
public static explicit operator Celsius(Fahrenheit fahr){ return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));}如下所示,调用用户定义的转换运算符来强制转换:
Fahrenheit fahr = new Fahrenheit(100.0f);Console.Write($"{fahr.Degrees} Fahrenheit");Celsius c = (Celsius)fahr;此转换运算符从源类型转换为目标类型。 源类型提供转换运算符。 不同于隐式转换,显式转换运算符必须通过转换的方式来调用。 如果转换操作会导致异常或丢失信息,则应将其标记为 explicit。 这可阻止编译器静默调用可能产生意外后果的转换操作。
省略转换将导致编译时错误 CS0266。
有关详细信息,请参阅使用转换运算符。
示例
下面的示例提供了 Fahrenheit 和 Celsius 类,其中每个类均提供转换为其他类的显式转换运算符。
class Celsius{ public Celsius(float temp) { Degrees = temp; } public float Degrees { get; } public static explicit operator Fahrenheit(Celsius c) { return new Fahrenheit((9.0f / 5.0f) * c.Degrees + 32); }}class Fahrenheit{ public Fahrenheit(float temp) { Degrees = temp; } public float Degrees { get; } public static explicit operator Celsius(Fahrenheit fahr) { return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32)); }}class MainClass{ static void Main() { Fahrenheit fahr = new Fahrenheit(100.0f); Console.Write($"{fahr.Degrees} Fahrenheit"); Celsius c = (Celsius)fahr; Console.Write($" = {c.Degrees} Celsius"); Fahrenheit fahr2 = (Fahrenheit)c; Console.WriteLine($" = {fahr2.Degrees} Fahrenheit"); }}// 输出:// 100 Fahrenheit = 37.77778 Celsius = 100 Fahrenheit示例
下面的示例定义结构 Digit,它表示单个的十进制数字。 将运算符定义为从 byte 到 Digit 的转换,但由于并非所有字节都可转换为 Digit,因此该转换应该应用显式转换。
struct Digit{ byte value; public Digit(byte value) { if (value > 9) { throw new ArgumentException(); } this.value = value; } // 定义从byte到Digit的显示转换 explicit operator: public static explicit operator Digit(byte b) { Digit d = new Digit(b); Console.WriteLine("转换已完成"); return d; }}class ExplicitTest{ static void Main() { try { byte b = 3; Digit d = (Digit)b; // 显示转换 } catch (Exception e) { Console.WriteLine("{0} 捕获到一成.", e); } }}参考资料
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
扩展阅读c#基础系列1---深入理解值类型和引用类型c#基础系列2---深入理解String引言在上篇文章深入理解值类型和引用类型的时候,有的小伙伴就推荐说一说
最近在看深入理解C#,发现这是一本很不错的书,将很多C#的知识点联系了起来,更像是一本C#历史书,从C#1一步步介绍到C#4。所以准备一边看,一边整理读书笔记。
先来一段代码引入主题。如果你可以直接说出代码的输出结果,说明本文不适合你。(代码引自《深入理解C#》第三版)classProgram{privatedelega
本文以实例形式讲述了C#泛型的用法,有助于读者深入理解C#泛型的原理,具体分析如下:首先需要明白什么时候使用泛型:当针对不同的数据类型,采用相似的逻辑算法,为了
本文实例讲述了C#使用SendMessage实现进程间通信的方法。分享给大家供大家参考。具体分析如下:为了深入理解消息机制,先来做一个测试项目在新建项目的For