int.TryParse非预期执行引发的思考
来源:https://blog.guoqianfan.com/2018/11/18/thinking-in-int-TryParse/
问题出现
这天在写一个页面,想谨慎些就用了int.TryParse
,结果出问题了。
代码如下:
int id = 1000;
//Request.QueryString["id"] = null
int.TryParse( Request.QueryString["id"], out id );
//使用 id 进行其他操作...
因为Request.QueryString["id"] = null
,所以我的预期是id=1000
。可是我错了,实际结果是id=0。测试多次都是这样。我感觉要出事了。
事实上我对TryParse一直存在这么个认知(以上面代码举例):
- 如果转换成功,id=转换后的值;
- 如果转换失败,不进行任何操作,id仍然是1000。
可是现在我知道我错了,更严重的是我按照这样的思维写了不少代码。。。还好我确保输入正确使其都能转化成功,至今没出什么幺蛾子。出幺蛾子的话我早就滚蛋了吧。
不过现在不是考虑这些的时候,工作要紧,就赶紧改了代码,先把新功能上线了再说...
问题分析
几天后,有空了,就开始研究这个问题,总结如下:
TryParse
转换失败时,out参数
返回的是什么?
网上搜了下,在stackoverflow上看到了这么一段话(谷歌翻译):
你是对的,如果失败,TryParse使用0。(MSDN非常清楚地说明了这一点)但你可以检查paseSuccess并返回你的默认值,如果这是你想要的。
现在发现当时看的是VB.NET...还好此时此刻这货特性和C#是一样的...不然又坑了...
既然提到了MSDN,那就去看看。果然,MSDN上在result
处写着这么一段话:
result
Int32
当此方法返回时,如果转换成功,则包含与s
中所包含的数字等效的 32 位无符号整数值;如果转换失败,则包含零。 如果s
参数为null
或为 Empty、格式不正确,或者表示小于 MinValue 或大于 MaxValue 的数,则转换失败。 此参数未经初始化即进行传递;最初在result
中提供的任何值都会被覆盖。
有这么几处重点:
- 当此方法返回时,如果转换成功,则包含与
s
中所包含的数字等效的 32 位无符号整数值;如果转换失败,则包含零。 - 此参数未经初始化即进行传递;最初在
result
中提供的任何值都会被覆盖。
”out参数“、“未经初始化即进行传递”,看到这些,我突然想到了out
参数的特性:“out
参数好像是不需要初始化的“。如果传入时不需要初始化,那么在TryParse方法内部,当转换成功时可以赋值(转换后的值);当转换失败时,也必须赋值,要赋值就必定是默认值。
到此我的疑惑已经解开了。搞了大半天,竟然是out关键字
的性质。恍然大悟的同时,又感觉到自己的C#基础的薄弱。。。
总结
TryParse
使用时,传入的out
参数的原始值会被覆盖掉,具体如下:
- 如果转换成功,使用转换成功后的值覆盖
- 如果转换失败,使用该类型的默认值覆盖
其他
转换失败时不使用默认值覆盖原始值的2种方法
既然已经了解了本质,当然也不能忘了咱们的初衷,那就是TryParse转换失败时,怎么不使用默认值覆盖我们设定的原始值?
下面分享一下在stackoverflow上看到的2种方法
//方法1、使用out参数的性质
int i = int.TryParse(s, out i) ? i : 42;
//方法2、扩展方法
public class Extensions
{
public static int? TryParse(string this Source)
{
if(int.tryparse ....
}
}
//使用
v = "234".TryParse() ?? 0
out
关键字和ref
关键字的区别
说到out
关键字,就不得不提ref
关键字,他们之间的区别是什么呢?
额,这个稍后我会再写一篇博文的,到时候此处会贴上链接,敬请期待...
参考
- SF:https://stackoverflow.com/questions/1078512/why-does-integer-tryparse-set-result-to-zero-on-failure?noredirect=1&lq=1
- SF:https://stackoverflow.com/questions/10693231/elegant-tryparse
- MSDN:Int32.TryParse Method
int.TryParse非预期执行引发的思考的更多相关文章
- int.TryParse非预期执行引发的思考 ASP.NET -- WebForm -- 给图片添加水印标记 Windows -- 使用批处理文件.bat删除旧文件
int.TryParse非预期执行引发的思考 问题出现 这天在写一个页面,想谨慎些就用了int.TryParse,结果出问题了. 代码如下: Copy int id = 1000; //Reque ...
- 曲演杂坛--一条DELETE引发的思考
原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...
- 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考
2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...
- c# 类型转换 int.TryParse() 方法
public static bool TryParse(string s, out Int32 result); 如果转换成功则返回true.否则返回false int.TryParse(string ...
- Go select 死锁引发的思考
Go select 死锁引发的思考 https://mp.weixin.qq.com/s/Ov1FvLsLfSaY8GNzfjfMbg一文引发的延续思考 上文总结 总结一 package main i ...
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
转自:http://www.cnblogs.com/leolis/p/3968943.html 在编程过程中,数据转换是经常要用到的,C#中数据转换的方法很多,拿将目标对象转换为 整型(int)来讲, ...
- C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别 <转>
作者:Statmoon 出处:http://leolis.cnblogs.com/ 在编程过程中,数据转换是经常要用到的,C#中数据转换的方法很多,拿将目标对象转换为整型(int)来讲,有四种方法 ...
- int.Parse()、int.TryParse()和Convert.ToInt32()的区别
1:int.Parse(一个参数) 此参数必须满足: 1 只能是字符串: 2 只能是 “整型” 字符串,即各种整型ToString()之后的形式,也不能为浮点型. 2:int.TryPa ...
- (int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
C#中(int).int.Parse().int.TryParse()和Convert.ToInt32()的区别 原文链接:http://www.cnblogs.com/leolis/p/3968 ...
随机推荐
- 【二分查找】POJ2456-Aggressive cows
[题目大意] 有N间牛舍和M头牛,告诉你每个牛舍的位置,求出两头牛之间最小距离的最大值. [思路] 二分判断两头牛之间的最小距离d,通过贪心法进行验证. #include<iostream> ...
- Java编程思想学习(三)----第三章:操作符
3.2使用Java操作符 操作符接受一个或多个参数,并生成一个新值. 操作符作用于操作数,生成一个新值.有些操作符可以改变操作数自身的值.几乎所以的操作符都只能操作“基本类型”.例外的操作符有“=”, ...
- 【常见加密方法】Base64编码&Tea算法简介
Base64编码 [Base64编码是什么] Base64是一种基于64个可打印字符来表示二进制数据的表示方法. ——维基百科 Base64,顾名思义,是基于64种可视字符的编码方式.这64种符号由A ...
- Codeforces Round #345 (Div. 2) E. Table Compression 并查集
E. Table Compression 题目连接: http://www.codeforces.com/contest/651/problem/E Description Little Petya ...
- Dell最近的几款显示器看上去还不错的样子
发现最近戴尔最近发布了两款的4k显示器P2415Q和P2715Q,价格还比较平易近人,淘宝价24寸3700,27寸4700,让人有点心动了.基本参数如下: 3840*2160分辨率 亮度350cd/m ...
- 浅谈linux系统的分区问题
转载:http://mtoou.info/linux-fenqu/ 很多然在装linux系统时面临的最大难题就是分区问题了,由于linux分区结构和windows不同,很多人对linux分区感觉非常不 ...
- 用yum安装完mysql后没有mysqld的问题
在Centos中用命令 yum install mysql安装数据库,但装完后运行mysqld启动mysql的时候提示找不到,通过 find / | grep mysqld 也没找到mysqld的目录 ...
- openwrt web管理luci界面修改
转自:http://blog.csdn.net/user_920/article/details/8504979 以前都没听过openwrt和luci,只接触过简单的php语言.由于工作原因,要修改下 ...
- Linux上安装使用SSH(ubuntu&&redhat)
转自:http://blog.csdn.net/zxs9999/article/details/6930736 Ubuntu安装使用SSH ubuntu默认并没有安装ssh服务,如果通过ssh链接ub ...
- Kubernetes应用迁移问题定位
这个帖子记录所有的应用迁移中遇到的问题. 关于镜像无法启动后无法定位问题 在原有的Dockerfile中修改,加入 RUN echo "aaa" > /etc/a.log C ...