C#中的Explicit和Implicit详情

目录
  • 一、Implicit和Explicit
    • 1、Implicit
    • 2、、Explicit

先上一段奇怪的代码:

if (dto.Payment == null) continue;

var entity = entries.FirstOrDefault(e => e.LedgerEntryID == dto.LedgerEntryID);

dto.Payment = entity?.Payment;

其中dto.Payment是一个PaymentDTO类的实例,entity?.Payment是一个Payment类的实例,PaymentDTO类和Payment类没有子父关系,所以不存在子类和父类之间的隐式转换。

奇怪的是Visual Studio的编译器没有提示任何编译错误。

打开PaymentDTO类的定义之后,发现了以下方法签名。

    public static implicit operator PaymentDTO(Payment payment)

从方法签名上看,这就是重写PaymentDTO类型的操作符,但并不是我以前常用的+,-,*,/, ==等。

查询MSDN之后,才了解到implicit和explicit是一对转换操作符。

一、Implicit和Explicit

1、Implicit

Implicit关键字用于声明隐式的用户定义类型转换运算符。它可以实现2个不同类的隐式转换 ,提高代码的可读性。但是需要注意使用隐式转换操作符之后,在编译时会跳过异常检查,所以隐式转换运算符应当从不引发异常并且从不丢失信息,否则在运行时会出现一些意想不到的问题。

例如当前PaymentDTO和Payment的定义如下

    public class Payment
    {
         public decimal Amount { get; set; }

    }
    public class PaymentDTO

    {
         public string AmountString { get; set; }
    }

如果需要将Payment隐式转换成PaymentDTO, 仅需声明PaymentDTO的隐式转换运算符

        public class PaymentDTO
        {
            public string AmountString { get; set; }

           public static implicit operator PaymentDTO(Payment payment)

            {
                return new PaymentDTO

                {
                    AmountString = payment.Amount.ToString("C2")
                };

            }
        }

调用时只需要直接赋值就可以

     class Program
        {
            static void Main(string[] args)
            {
                PaymentDTO dto = new Payment { Amount = 1 };

                Console.WriteLine(dto.AmountString);

                Console.Read();

            }
        }

2、、Explicit

Explicit关键字声明必须通过转换来调用的用户定义的类型转换运算符。不同于隐式转换,显式转换运算符必须通过转换的方式来调用,如果缺少了显式的转换,在编译时就会产生错误。

例如现在我们将前面PaymentDTO类中定义的转换操作符从Implicit变为Explicit


        public class PaymentDTO

        {

            public string AmountString { get; set; }
            public static explicit operator PaymentDTO(Payment payment)

            {

               return new PaymentDTO

                {
                    AmountString = payment.Amount.ToString("C2")

                };
            }
        }

这时候由于Main方法中没有显式转换,所以编译器出错,提示Cannot implicitly convert type 'ExplicitImplicit.Payment' to 'ExplicitImplicit.PaymentDTO'. An explicit conversion exists (are you missing a cast?)

如果想要编译器通过编译, 只需要做一个显示转换即可

        class Program

        {
            static void Main(string[] args)
            {
                PaymentDTO dto = (PaymentDTO)new Payment { Amount = 1 };

                Console.WriteLine(dto.AmountString);

               Console.Read();

            }
        }

到此这篇关于C#中的ExplicitImplicit详情的文章就介绍到这了,更多相关C#中的ExplicitImplicit内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#中explicit与implicit的深入理解

    前言 今天在研究公司项目框架的时候看到了下面的用法,public static implicit operator JsonData(int data); .貌似很久没用过这种隐式转换的写法了,因此重新温习一下C#中转换相关的知识. explicit 和 implicit 属于转换运算符,如用这两者可以让我们自定义的类型支持相互交换 explicti 表示显式转换,如从 A -> B 必须进行强制类型转换(B = (B)A) implicit 表示隐式转换,如从 B -> A 只需直接赋值(A

  • 实例分享C#中Explicit和Implicit用法

    今天在Review一个老项目的时候,看到一段奇怪的代码. if (dto.Payment == null) continue; var entity = entries.FirstOrDefault(e => e.LedgerEntryID == dto.LedgerEntryID); dto.Payment = entity?.Payment; 其中dto.Payment是一个PaymentDTO类的实例,entity?.Payment是一个Payment类的实例,PaymentDTO类和Pa

  • C#中的Explicit和Implicit详情

    目录 一.Implicit和Explicit 1.Implicit 2..Explicit 先上一段奇怪的代码: if (dto.Payment == null) continue; var entity = entries.FirstOrDefault(e => e.LedgerEntryID == dto.LedgerEntryID); dto.Payment = entity?.Payment; 其中dto.Payment是一个PaymentDTO类的实例,entity?.Payment是

  • C++中的explicit关键字实例浅析

    在C++程序中很少有人去使用explicit关键字,不可否认,在平时的实践中确实很少能用的上.再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决.但稍微留心一下就会发现现有的MFC库或者C++标准库中的相关类声明中explicit出现的频率是很高的.了解explicit关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用.既然C++语言提供这种特性,我想在有些时候这种特性将会非常有用. 按默认规定,只用传一个参数的构造函数也定义了一个隐式转换.举

  • 关于Python中的if __name__ == ‘__main__’详情

    目录 1.程序入口 2.__name__是什么? 场景1:直接运行脚本 场景2:从其他脚本导入 3.__name__可以显示包路径 5.测试模块里函数 关于在学习Python的过程中,遇到的这类似的代码: if __name__ == "__main__":     print("Hello World!") 1.程序入口 对于很多编程语言来说,程序都必须要有一个入口,比如 C,C++,以及完全面向对象的编程语言 Java,C# 等.如果你接触过这些语言,对于程序入

  • 在 ASP.NET Core 中自动启用 CAP 事务详情

    目录 一.发布端事务 二.消费端事务 1.创建一个 CAP 过滤器 2.配置过滤器 本篇文章旨在描述如何在 ASP.NET Core项目中并以一种简便的方式启用CAP事务,因为在我们的示例中都是直接演示比较直观的方式,没有进行封装,有些初学者同学不太会,找到问我如何封装,本篇文章主要是一个简单的演示. 在本示例中 ,我们主要是基于 Entity Framework 来进行演示,如果你使用其他 Orm 原理类似,大家参考即可. 一.发布端事务 由于大部分人都是在 Web 中使用,所以可以通过使用

  • Go语言中的字符串拼接方法详情

    目录 1.string类型 2.strings包 2.1 strings.Builder类型 2.2 strings.Reader类型 3.bytes.Buffer 3.1 bytes.Buffer:写数据 3.2 bytes.Buffer:读数据 4.字符串拼接 4.1 直接相加 4.2strings.Builder 4.3 strings.Join() 4.4 bytes.Buffer 4.5 append方法 4.6 fmt.Sprintf 5.字符串拼接性能测试 1.string类型 s

  • java中的GC收集器详情

    目录 1.GC(Garbage collection ) 2.GC算法 2.1标记活动对象 2.2 删除空闲对象 2.3 标记清除(Mark-Sweep) 2.4 清除压缩(Mark-Sweep-Compact) 2.5 标记和复制 3.JVM GC 3.1 JVM GC事件 3.2 Serial GC 3.3 Parallel GC 3.4 Concurrent Mark and Sweep 3.5 G1 –垃圾优先 4.总结 1.GC(Garbage collection ) 程序内存管理分

  • Java 中的类和对象详情

    目录 1.类的定义 2.类中变量的类型 3.构造方法 4.重载方法 5.继承 5.1 重写方法 6.创建对象 7.访问实例变量和方法 8.比较对象 8.1 使用 == 比较对象 8.2 使用 equals() 比较对象 类可以看成是创建Java对象的模板 1.类的定义 public class Dog { String name; int age; void eat() { } void sleep() { } } 2.类中变量的类型 局部变量:在方法或语句块中定义的变量被称为局部变量.变量声明

  • Vue3中的Refs和Ref详情

    小编同样和大家分享关于Vue3中的数据相应的问题,下面我们来例举一个这样的例子 Vue.createApp({ template: `<div>{{ nameObj.name }}</div>`, setup() { const { reactive } = Vue const nameObj = reactive({name:'lilei',age:18}) setTimeout(() => { nameObj.name = 'hanmeimei' },2000) retu

随机推荐