C#函数的默认参数——填坑记
昨天踩了一个坑。默认参数 + 增量发布的坑。
过程是这样的。
1. 有一个底层的方法,格式形如
void Test<T>(int p1, string p2, Func<T> p3){}
代码所在的项目的程序集名称假设为 A.dll
2. 引用这个方法的代码有多处,大部分分布在两个项目里面,对应的项目的程序集假设为B.dll和C.dll
3. 处于优化和解决bug的考虑,扩展了上述底层方法,改为:
void Test<T>(int p1, string p2, Func<T> p3, Func<T, bool> p4 = null){}
增加了第四个有默认值得参数。
这里提一下自己的理解误区:我一直以为上面的写法是等于:
void Test<T>(int p1, string p2, Func<T> p3){}
+
void Test<T>(int p1, string p2, Func<T> p3, Func<T, bool> p4){}
4. 改完了底层的那个方法后,重新编译获得A.dll,和相应调用了四个参数方法的代码所在的B.dll
5. 增量发布A.dll和B.dll。
...
6. 线上报错,异常信息提示源头为C.dll,异常明细是Method not found '!!0 Test(Int64, System.String, System.Func`1)'
7. 一脸懵逼 + 二脸懵逼 + 。。。 + 关它么事???
8. 差点准备回滚覆盖了。同事提醒,既然说它有问题,就更新它呗。依言照办,线上恢复。
轮到我百思不得其解了,为什么C.dll找不到这个方法呢?A里面不在呢吗?
后来我用反射工具查看了两个C.dll里面的代码。如下:
原始代码:

A.dll改之前,通过反编译看到的此处代码:

A.dll改成带默认参数之后:

重点在后面的那个null值。
也就是说,将函数Test后面追加了一个带默认值的参数后,相应原来调用时没有传第四个参数的地方,本质上是传了参数的,参数值为默认值。而函数的默认参数则像是一种语法糖,替程序员节省了输入null值的步骤,但是编译后的代码中,确实有的。
所以在上面的情况中,增量发布时,必须一起更新C.dll。否则,旧的DLL文件无法调用新的A.dll中的函数了。
补充一个。A.dll的反射获得的信息:

由上面这个图可以清晰的看到,这个函数,只有一个四个传参的定义,没有三个传参的重载。
相关阅读:
https://www.cnblogs.com/gdouzz/p/6889163.html
C#函数的默认参数——填坑记的更多相关文章
- Appium+python自动化(十三)- 输入中文 - 一次填坑记(超详解)
简介 无论你在哪里,在做什么都会遇到很多坑,这些坑有些事别人挖的,有些是自己挖的.别人挖的叫坑人,自己挖的叫自杀,儿子挖的叫坑爹.因此在做app自动化道路上也不会是一帆风顺的,你会踩很多坑,这些坑和你 ...
- UiAutomator2.0升级填坑记
UiAutomator2.0升级填坑记 SkySeraph May. 28th 2017 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sk ...
- Android项目开发填坑记-Fragment的onBackPressed
Github版 CSDN版 知识背景 Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的.这里简称为Fragment ...
- 浅谈html5 video 移动端填坑记
这篇文章主要介绍了浅谈html5 video 移动端填坑记,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 本文介绍了html5 video 移动端填坑记,分享给大家,具体 ...
- Python默认参数的坑
默认参数的坑 定义一个函数,传入一个list,添加一个end再返回 def add_end(L=[]): L.append('END') return L 正常调用时,结果似乎不错 print add ...
- Java web 开发填坑记 2 -如何正确的创建一个Java Web 项目
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72566261 本文出自[赵彦军的博客] Java web 开发填坑记 1-如何正确 ...
- C++中函数的默认参数
使用方法: (1)在函数声明或定义时,直接对参数赋值,该参数就是默认参数. (2)在函数调用时,省略部分或全部参数,这时就会使用默认参数进行代替. 注意事项: (1)一般在声明函数是设置默认参数. 如 ...
- Android项目开发填坑记-Fragment的onAttach
背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...
- Android项目开发填坑记-so文件引发的攻坚战
故事的最初 我负责的项目A要求有播放在线视频的功能,当时从别人的聊天记录的一瞥中发现百度有相关的SDK,当时找到的是Baidu-T5Player-SDK-Android-1.4s,项目中Demo的so ...
随机推荐
- SSM整合Activiti
1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
- (Android系统目录结构)目录预览
Android系统进入设备后,查看根目录下文件系统,如下: 重要目录和文件说明:mnt 挂载点目录etc 系统主要配置文件system Android 系统文件sys Linux 内核文件proc 运 ...
- 潭州课堂25班:Ph201805201 django 项目 第三十六课 后台文章管理(课堂笔记)
get 请求, 1,获取文章标签 , 2,拿到前台传来的值, 3,根据前台传来的值在数据库中查询 4.,返回数据到前台,渲染, 分页算法 : 在 utils 下创建 paginator_script ...
- 潭州课堂25班:Ph201805201 django框架 第二课 url,,include,kwargs,name的使用 (课堂笔记)
url 路由配置 这里的 name 由用户输入,得到参数 /<>/是获取用户输入值 这里的 name 默认接收的是 str 如果要接收 int 时: 当输入参数非数字时提示错误 最常用是 ...
- [PA2014]Zadanie
[PA2014]Zadanie 题目大意: 一棵\(n(n\le3\times10^5)\)个点的树,每个点上有\(a_i\)个人.树上所有人到\(i\)号点距离之和为\(b_i\).已知\(\{b_ ...
- 轻松理解Redux原理及工作流程
轻松理解Redux原理及工作流程 Redux由Dan Abramov在2015年创建的科技术语.是受2014年Facebook的Flux架构以及函数式编程语言Elm启发.很快,Redux因其简单易学体 ...
- BZOJ4910 : [Sdoi2017] 苹果树
问题等价于树形依赖背包,允许一条链每个点各免费一次. 设$f[i][j]$表示按DFS序考虑到$i$,体积为$j$的最大收益. 先放入不能免费的物品,等遍历完儿子后再放入必选的物品,那么$i$到根路径 ...
- Flask蓝图
它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看客户列表的功能,后来你又加入了一个添加客户的功能(add_user)模块, 然后又加入了一个 ...
- Android Studio 解决ADB检测不到手机导致无法连接的问题
ADB的全称是Android Debug Bridge,是用来管理模拟器和真机的通用调试工具. 开USB调试 方法:手机设置 - 开发人员选项 - USB调试 - 勾选(开发者调试被隐藏了,在关于手机 ...
- JQ04
1.JQ插件 使用插件扩展jq的功能 1)插入插件的步骤: 引入JQ文件,引入插件,若有用到css,需要引入css.使用插件. 2)jquery.color.js <!DOCTYPE html& ...