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 = };
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 = };
Console.WriteLine(dto.AmountString);
Console.Read();
}
}
总结
- Implicit提高了代码的可读性,但程序员需要自己保证转换不引发异常且不丢失信息
- Explicit可阻止编译器静默调用可能产生意外后果的转换操作。
- 前者更易于使用,后者能向阅读代码的每个人清楚地指示您要转换类型
C#中的Explicit和Implicit的更多相关文章
- C#中的explicit和implicit了解一下吧
今天在研究公司项目框架的时候看到了下面的用法,public static implicit operator JsonData(int data);.貌似很久没用过这种隐式转换的写法了,因此重新温习一 ...
- 【RS】CoupledCF: Learning Explicit and Implicit User-item Couplings in Recommendation for Deep Collaborative Filtering-CoupledCF:在推荐系统深度协作过滤中学习显式和隐式的用户物品耦合
[论文标题]CoupledCF: Learning Explicit and Implicit User-item Couplings in Recommendation for Deep Colla ...
- C#中转换运算符explicit、implicit、operator、volatile研究
C#中的这个几个关键字:explicit.implicit与operator,估计好多人的用不上,什么情况,这是什么?字面解释:explicit:清楚明白的;易于理解的;(说话)清晰的,明确的;直言的 ...
- operator、explicit与implicit
说这个之前先说下什么叫隐式转换和显示转换 1.所谓隐式转换,就是系统默认的转换,其本质是小存储容量数据类型自动转换为大存储容量数据类型. 例如:float f = 1.0: double d=f:这样 ...
- explicit和implicit
explicit是C++中的一个关键字,只用于修饰只有一个参数的构造函数: class A{ explicit A(const T obj); }; 该关键字告诉编译器该类只能显式的转换,不能隐式(i ...
- C++中的explicit
首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数 ...
- C++中的explicit关键字的用法
一.explicit作用: 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换. 二.explicit使用注意事项: ...
- C++中关键字explicit的作用
C++中, 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色. 1 是个构造器 ,2 是个默认且隐含的类型转换操作符. 所以, 有时候在我们写下如 AAA ...
- explicit 和 implicit 的用法
explicit 和 implicit 属于转换运算符,如用这两者可以让我们自定义的类型支持相互交换 explicti 表示显式转换,如从 A -> B 必须进行强制类型转换(B = (B)A) ...
随机推荐
- Strategic Game
Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- LR多分类推广 - Softmax回归*
LR是一个传统的二分类模型,它也可以用于多分类任务,其基本思想是:将多分类任务拆分成若干个二分类任务,然后对每个二分类任务训练一个模型,最后将多个模型的结果进行集成以获得最终的分类结果.一般来说,可以 ...
- ⑧bootstrap组件 文字图片 下拉菜单 按钮组 使用基础案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue.js项目安装
Vue.js 安装 NPM 方法安装vue.js项目 npm 版本需要大于 3.0,如果低于此版本需要升级它: # 查看版本 $ npm -v 2.3.0 #升级 npm npm install np ...
- 分享如何将git项目导入GitHub(附创建分支)
前言:我们应该很多都会有自己的私有项目,大多情况都是存放在自己的硬盘中,今天我分享一下怎么讲自己的私有项目更新到GitHub上,这样再也不用担心项目丢失了. 一:下载git 下载链接git链接,根据自 ...
- 在微信端使用video标签,播放结束会出现QQ浏览器推荐视频的解决办法(vue)
会出现播放结束显示QQ浏览器推荐视频的原因:(我是vue的项目,而且我是新手,只是单纯的给大家分享一个方法,代码比较low请自动忽略) 因为在x5(QQ浏览器)内核中,把video标签劫持了,只要是检 ...
- (原创)遗传算法C++实现
本文没有对遗传算法的原理做过多的解释 基础知识可以参考下面的博客:http://blog.csdn.net/u010451580/article/details/51178225 本实验用到的变异用到 ...
- Python3学习笔记 - 准备环境
前言 最近乘着项目不忙想赶一波时髦学习一下Python3.由于正好学习了Docker,并深深迷上了Docker,所以必须趁热打铁的用它来创建我们的Python3的开发测试环境.Python3的中文教程 ...
- C#中??和?分别是什么意思?
在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; 是正确的,int i=null ...
- [转载] hessian学习
转载自http://www.cnblogs.com/yjmyzz/p/hessian-helloworld.html hessian是一个采用二进制格式传输的服务框架,相对传统soap web ser ...