原文:http://msmvps.com/blogs/Senthil/
Overload resolution and null
最近在努力学习英语,所以决定自己来翻译一些c#和.NET相关的技术文章,既可学习英语,又能学习到c#和.NET的技术,可谓是一举两得的事情。如果翻译不到位,请谅解,也希望能得到大家友善的指正。

我的同事Soundar发现一个相当有趣的行为
 1: class Test
  2: {
  3:     public static void Main()
  4:     {
  5:         Test test = null;
  6:
  7:         Console.WriteLine("{0}", test);
  8:         Console.WriteLine("{0}", null);
  9:     }
 10: }

如果你运行上面代码,你就会发现第7行打印了一空行,而第8行导致了一个ArgumentNullException异常。注意test的引用也是null,所以这会令你惊讶,因为运行时这两行不一样的行为。

它当然也让我惊讶并使我非得深究导致区别的原因不可。我认为相同的参数值在同样的运行时,产生了不同的结果,是因为编译器的操作——可能是方法重载。果然,第7行和第8行要求不同的重载来解决。

第7行使用了下面重载
public static void WriteLine(string format, object arg0);
第8行使用了下面重载
public static void WriteLine(string format, params object[] arg);

使用Reflector查看IL代码显示当arg为null时第二种重载会抛出异常,而第一种重载会把arg0转变成一个对象数组,并要求第二种重载。

然而,为什么编译器会现在两种不同的重载呢?
直观地,当只传入一个参数给调用方法时,你期望重载机制会更倾向于选择单个参数的重载,而不是可变参数的重载。这就是编译器对第七行选择重载一的原因。
在第八行的情况不一样,null直接分配给参数arg0和arg,重载机制必须选择最好的函数,这个时候它选择了参数为对象数组的重载方法。
这显得和直观相反,直到你拥有类似下面的代码:
1: class Test
  2: {
  3:     public static void Main()
  4:     {
  5:         SubTest subTest = null;
  6:         M(subTest);
  7:     }
  8:
  9:     static void M(Test t) { Console.WriteLine("Test"); }
 10:     static void M(SubTest s) { Console.WriteLine("SubTest"); }
 11: }
 12:
 13: class SubTest : Test { }
你不会感到惊讶运行到第六行时是要求重载方法M(SubTest),你会吗?
在C#规范的规则里确定最好的匹配是这样说的:
“给出一个从类型S转换为T1的隐形转换C1和一个从类型S转换为T2的隐形转换C2,这两个转换方式中选择哪个最好有下面的几点决定:
(1)如果类型T1和类型T2相同,两种转换性能一样。
(2)如果S是T1类型,则C1是更好的转换。
(3)如果S是T2类型,则C2是更好的转换。
(4)如果存在类型T1向类型T2隐性转换,并且不存在T2向T1的隐形转换,那么C1是更好的转换方法。
(5)如果存在类型T2向类型T1隐性转换,并且不存在T1向T2的隐形转换,那么C2是更好的转换方法。
....”
在上面代码中,SubTest(T1)可以隐性地转换为Test(T2),所以编译器选择了M(SubTest).
在我们的代码中,编译器努力在null转换为对象object和null转换为数组object[]中选择最好的转换方式,根据上面的转换原则,object[]能隐性地转换为object,所以重载机制选择了WriteLine(string format, params object[] arg). 在解决null参数的案例中,修饰的参数并没有发挥作用。
非常有趣?是不是呢?

转载于:https://www.cnblogs.com/zoupeiyang/archive/2009/08/12/1544350.html

翻译:重载解决和Null相关推荐

  1. 翻译pdf中的英文 python_浅谈python实现Google翻译PDF,解决换行的问题

    我们复制PDF到Google翻译时,总是会出现换行的情况,如果自己手动去除,那就太麻烦了. 那么用Python就可以解决,复制到粘贴板以后,Python程序自动可以把\n换成空格,然后我们就可以复制到 ...

  2. 申请邓白氏D-U-N-S编码遇到两个公司名称一样英文翻译的解决方法

    申请邓白氏D-U-N-S编码遇到两个公司名称一样英文翻译的解决方法 参考文章: (1)申请邓白氏D-U-N-S编码遇到两个公司名称一样英文翻译的解决方法 (2)https://www.cnblogs. ...

  3. 谷歌浏览器无法翻译已解决

    谷歌浏览器自带的翻译对我们来说用处还是很大的,但有的时候突然间就会变成'无法翻译此网页',下面针对此问题讲解一下解决方案. 目前比较靠谱的解决方案是更改host文件,这是因为谷歌浏览器使用的翻译网站域 ...

  4. 谷歌浏览器无法翻译中文解决办法

    谷歌浏览器的内置翻译无法使用 解决步骤 搜索彩云小译或者直接点击此按钮彩云小译 然后在官网下载彩云小译插件 手动进入谷歌拓展程序 或 新建网页,输入网址chrome://extensions进入 拖拽 ...

  5. python实战爬虫有道翻译与解决{“errorCode”:50}反爬虫问题

    title: python实战爬虫有道翻译与解决有道翻译反爬虫问题 date: 2020-03-22 20:21:12 description: 最近在学Python,一直没有尝试过实战.于是昨天试了 ...

  6. 【Java基础】妙用Optional解决判断Null为空问题

    一.背景 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException. 回顾以前对null的处理方式: package com.biyu.study ...

  7. 谷歌翻译失效解决方法

    谷歌翻译失效解决方法 首先使用指令查找ip nslookup google.cn 得到一个ip 修改hosts文件(将ip切换成自己查到的最新ip) #hosts文件位置:C:\Windows\Sys ...

  8. OPENCV3读取avi,解决返回NULL问题

    OPENCV调用cvCreateFileCapture返回NULL 最近在c++使用视频处理项目,当capture = CvInvoke.cvCreateFileCapture(file)获取视频信息 ...

  9. @value 默认值为null_JAVA8之妙用Optional解决判断Null为空的问题

    引言在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示 在这种情况下,有如下代码 user.g ...

最新文章

  1. C语言--指针函数和函数指针
  2. sublime text 3安装及使用
  3. CSS-posiziton
  4. Dev Lake 0.4.0 版本:开源、开放的研发效能数据平台
  5. vdp备份oracle系统,VDP文件级恢复需要在用VDP备份的机器上浏览
  6. gradle:Creating New Gradle Builds
  7. Expanding Rods(二分)
  8. mac os maven_如何在Mac OS上安装Maven
  9. 130242014051 《商品详情模块》需求分析与设计实验课小结
  10. 第四百零四天 how can I 坚持
  11. 打包工具SetupFactory 9 的使用
  12. php批量查qq号码是否冻结,PHP批量检查网站的sitemap是否存在
  13. OpenModelica.VehicleInterfaces离线库安装
  14. go与python的前景_golang程序员前景怎么样?Python、Java、go语言的优势互比
  15. SAP用户应该知道的销售订单(协议)的重要控制逻辑
  16. 三分搜索--hdu2241 考研路茫茫——早起看书
  17. WIN10系统-Deepin系统重装
  18. Day 6.重大医疗伤害事件网络舆情能量传播过程分析*———以“魏则西事件”为例
  19. 子豪兄-YOLOv3
  20. 【论文阅读】Region Proposal by Guided Anchoring

热门文章

  1. cesium获取模型高度_Cesium中地形数据的加载
  2. python开发面试笔试题_python集合面试笔试题
  3. linux命令只有一个文件,一天一个Linux基础命令之文件查看命令more
  4. IDEA maven依赖下载失败
  5. java构造方法与重载牛肉粉,IT兄弟连Java基础视频教程
  6. eas库存状态调整单不能反审核_仓储管理笔记:库存差错、毁损赔偿、自用管理、组织架构.........
  7. c语言水平制表符怎么才能占16列,水平制表符是?其作用?
  8. arm汇编指令WFI和WFE
  9. GP学习(五)—ArcGIS Toolbox Reference dialog box
  10. postgresql存图片字段类型_C# 使用 PostgreSQL 存储图片二进制数据