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并返回你的默认值,如果这是你想要的。

既然提到了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关键字,他们之间的区别是什么呢?

额,这个稍后我会再写一篇博文的,到时候此处会贴上链接,敬请期待…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值