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类和Payment类没有子父关系,所以不存在子类和父类之间的隐式转换。

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

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

    public static implicit operator PaymentDTO(Payment payment)

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

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

Implicit和Explicit

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();

            }

        }

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();

            }

        }

总结

  • Implicit提高了代码的可读性,但程序员需要自己保证转换不引发异常且不丢失信息
  • Explicit可阻止编译器静默调用可能产生意外后果的转换操作。
  • 前者更易于使用,后者能向阅读代码的每个人清楚地指示您要转换类型
时间: 2024-10-29 06:45:10

C#中的Explicit和Implicit的相关文章

C#中的explicit和implicit了解一下吧

今天在研究公司项目框架的时候看到了下面的用法,public static implicit operator JsonData(int data);.貌似很久没用过这种隐士转换的写法了,因此重新温习一下C#中转换相关的知识. 作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/10898582.html implicit implicit 关键字用于声明隐式的用户自定义的类型转换运算符. 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型

operator、explicit与implicit

说这个之前先说下什么叫隐式转换和显示转换 1.所谓隐式转换,就是系统默认的转换,其本质是小存储容量数据类型自动转换为大存储容量数据类型. 例如:float f = 1.0: double d=f:这样就是把float类型的f隐式转换成double类型了!但其实系统帮我们做了类似如下的工作: float f = 1.0: double d=(double)f: 对于表示数值的基本数据类型来说,数值范围小的数据类型转换成数值范围大的数据类型可以进行隐式转换,而反过来则必须进行显示转换 2.显式类型转

深入理解C++中的explicit关键字

深入理解C++中的explicit关键字 [email protected] http://blog.csdn.net/kezunhai C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式). 关于explicit关键字,先看看MSDN上的解释: This keyword is a declaration speci

C++中的explicit关键字的用法

一.explicit作用: 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. 二.explicit使用注意事项: explicit 关键字只能用于类内部的构造函数声明上. explicit 关键字作用于单个参数的构造函数. 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换 参考博客:http://www.cnblogs.com/this-54327365

C#关键字explicit、implicit、operator 、unsafe 、fixed

今天遇到一些一般不常用,但说不定什么情况下就能用到的C#关键字. 转换关键字 explicit 定义强制转换 // Must be defined inside a class called Fahrenheit: public static explicit operator Celsius(Fahrenheit fahr) { return new Celsius((5.0f / 9.0f) * (fahr.degrees - 32)); } implicit 定义隐性转换 // User-

类型转换关键字explicit与implicit的用法

这篇是个语法文,虽然这两个关键字比较陌生,但让自己有个印象不是坏事 explicit 明确转换与 implicit 隐含转换都是c#内的关键字,目的是让一个类型 转换到另外一个类型,最常见的例子就是由double转换到int时要使用明确转换, 而int转换到double的时候是使用隐含转换. double d = default(double); int i = default(int); //double 转换为 int 时必须明确定义类型 //否则编译器会丢出错误 i = (int)d; /

C# 参考之转换关键字:operator、explicit与implicit

operator operator 关键字用于在类或结构声明中声明运算符.运算符声明可以采用下列四种形式之一: public static result-type operator unary-operator ( op-type operand ) public static result-type operator binary-operator ( op-type operand, op-type2 operand2 ) public static implicit operator co

DbContext 中的 Explicit interface implementation

疑惑 前段时间一直再用Entity Framework 6,写了一些公用的方法,在这个过程中发现了DbContext实现的接口IObjectContextAdapter,可以通过这个接口访问到更底层的ObjectContext对象,比如 ((IObjectContextAdapter)ctx).ObjectContext 当时就觉得很奇怪,为什么不能直接获取,而需要一次转换,主要是奇怪C#是通过什么形式把ObjectContext给hide住的,不过当时也没多想,忙于完成工作.最近比较系统的再过

C++中的explicit关键字介绍

C++中的关键字explicit主要是用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换.类构造函数默认情况下声明为隐式的即implicit. 隐式转换即是可以由单个实参来调用的构造函数定义了一个从形参类型到该类类型的隐式转换.编译器在试图编译某一条语句时,如果某一函数的参数类型不匹配,编译器就会尝试进行隐式转换,如果隐式转换后能正确编译,编译器就会继续执行编译过程,否则报错. explicit关键字只能用于类内部的构造函数声明上,而不能用在类外