最近项目开发中遇到了两个bug,第一个问题是策划配置数据表的string字段列,默认没有配置数据,导表之后生成string为空,在程序使用此字段转换为数字的时候出现报错。第二个问题是服务器发过来一个int类型的数值,然后在使用事件分发的时候,出现了装箱和拆箱操作,在进行强转uint类型的时候出现报错,报错的堆栈指向的是事件分发器里面的逻辑代码,通过层层排查最终发现竟然是拆箱的时候出错了,坑啊。

下图就是拆箱出错的测试用例:

其中1、2、3的转换操作都是正确的,第4种转换在手机APP上面竟然会出现crash。

对于上面出现的问题进行反思和总结如下:

一、装箱和拆箱

装箱:把值类型转成引用类型
拆箱:把引用类型转成值类型

从定义中可以看出装箱和拆箱操作只可能发生在值类型之间的转换,引用类型之间是不会出现装箱和拆箱操作的。

装箱:object obj=1;

上述代码即为一次装箱过程。系统首先会建立一个索引为[0] object类型的局部变量,将整形数1从栈中取出放在栈顶,执行box指令并在托管堆上申请System.Int32所需内存空间。将栈上的变量弹出存储到索引为0的局部变量中。此操作不可避免的要在堆上申请内存空间,并将堆栈上的值类型数据复制到申请的堆内存空间上,这肯定是要消耗内存和cpu资源的。

拆箱:int x=(int)obj;

上述代码即为一次拆箱过程。系统首先会建立一个索引为[1]的int32类型局部变量,将堆上索引为[0]的变量值取出压入栈顶,执行unbox.any指令,生成System.Int32地址指针并读取数据存入栈。后将栈上的变量存储到索引为[1]的int32类型变量中。拆箱操作的执行过程和装箱操作过程正好相反,是将存储在堆上的引用类型值转换为值类型并给值类型变量。

由于装箱操作和拆箱操作是要额外耗费cpu和内存资源的,所以项目开发中尽量使用泛型定义来避免装箱和拆箱的出现。

二、数值类型之间的转换--(int)和 int.Parse()和int.TryParse()和Convert.ToInt32()

private 

对上面的测试代码进行总结:

1、null 空类型的转换:int.Parse()和直接强转是会报错的,其他转换返回0

2、number 数字类型的转换:Convert.ToInt32()是参与四舍五入取值,强转是直接向下取整。对于大值转向小值,Convert.ToInt32()和int.Parse()都会报错,

虽然强转不会报错,但是精度不对,会对原数据进行截取,结果也是错误的。

3、string 字符串类型的转换:对于空字符和浮点数的string的转换int,只有int.TryParse()不会报错,其他都会报错。策划配置表经常出现类似的配置问题,需要注意。

综上,我们对数据转换要特别谨慎,选择合适的函数,才能保证不会出错。建议如果是数值类型之间的转换直接可以强转。如果是字符串类型的转换建议int.Parse()和int.TryParse() 如果是装拆箱建议用Convert.ToInt32()。实在不知道选择哪个类型建议用int.TryParse(),做好对转换返回值bool的判断就可以了。

by 2020-06-15 周日 凌晨

decimal转换为int_“System.InvalidCastException 指定的转换无效”问题的反思和总结相关推荐

  1. 关于Linq to SQL 的“异常详细信息: System.InvalidCastException: 指定的转换无效。”

    开发环境:VS2010,SQL Server2005,Windows7,使用LINQ to SQL作为ORM 运行环境:Windows2003(IIS6),.NET 3.5 SP1,SQL Serve ...

  2. .NET 调用JS:WebBrowser.Document.InvokeScript 方法抛出“指定的转换无效”异常的原因

    .NET 调用JS:WebBrowser.Document.InvokeScript 方法抛出"指定的转换无效"异常的原因 参考文章: (1).NET 调用JS:WebBrowse ...

  3. SQLServer还原 指定的转换无效解决方法

    背景:最近在迁移一个业务系统,还原数据库时遇到一个问题:"指定的转换无(SqlManagerUI)".数据库是MS SQLServer, 备份文件是DBA直接给我的.经过分析,可能 ...

  4. Vue+Springboot上传图片将 Base64 码转换为图片保存在指定文件夹

    Vue+Springboot上传图片将 Base64 码转换为图片保存在指定文件夹 前言 一.Vue 前端 一.五 注意!!! 二.Springboot 后端 引入Base64依赖 在项目里新建 ut ...

  5. php mysql日期戳转时间戳_php日期转时间戳,指定日期转换成时间戳

    写过PHP+MySQL的程序员都知道有时间差,UNIX时间戳和格式化日期是我们常打交道的两个时间表示形式,Unix时间戳存储.处理方便,但 是不直观,格式化日期直观,但是处理起来不如Unix时间戳那么 ...

  6. 日期格式转换成时间戳格式php,php日期转时间戳,指定日期转换成时间戳

    有朋友问php与mysql有没有办法把日期转时间戳或把指定日期转换成时间戳呢,其实这个是有并且还非常的简单,下面我来给大家介绍介绍. 一.在MySQL中完成 这种方式在MySQL查询语句中转换,优点是 ...

  7. 无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型

    今天写winform的时候遇到一个问题,提示: 无法将 lambda 表达式 转换为类型"System.Delegate",因为它不是委托类型, 主要是为了在子线程中更新UI线程, ...

  8. arcgis 将地图点转换为屏幕坐标_ArcGIS中自定义坐标系转换

    ArcGIS中所有地理数据集均需要用于显示.测量和转换地理数据的坐标系. 9 10 15 20 25 30 35 c / n db 万方数据 天线 信源 模块 处理 射频 数模 中频 基带 比特流 转 ...

  9. 将任意一个十进制数数字转换为二进制形式,并输出转换后的结果

    package com.llh.demo; import java.util.Scanner; /**  *   * @author llh  *  */ public class Demo13 { ...

最新文章

  1. php连接oracle10g,php连接Oracle Database 10g Express Edition
  2. 不擅长物理科学计算机吗,物理难学否?答案因人而异,高二同学3 + 3选科莫要太随意...
  3. leetcode718. 最长重复子数组
  4. 解决Tomcat8及Tomcat7下http的post、get请求中参数中文乱码问题
  5. 抢先看!Kubernetes v1.21 新特性一览
  6. Windows巡检IIS指标脚本(PowerShell实现)
  7. Cell子刊:盗梦空间成真,科学家成功进入他人梦境,并与之“交流对话”
  8. 不到70行 Python 代码,轻松玩转 RFM 用户分析模型(附案例数据和代码)
  9. SpringMVC工作原理的介绍
  10. sql中毫秒数与格式化时间的转换
  11. SQL Server 2017 AlwaysOn AG 自动初始化(九)
  12. 大学生网页制作期末作业——HTML+CSS+JavaScript制作成都旅游网页设计与实现12个页面 web前端课程设计代码 web课程设计 HTML网页制作代码
  13. editplus远程连接云服务器
  14. 数据在网络中如何传输的
  15. 接口技术七段数码管c语言,031 实例7-七段数码管绘制
  16. 前长江基金董事长王含冰被开除党籍和公职 涉嫌职务犯罪
  17. HM代码阅读2:AMVP预测函数Void TEncSearch::xEstimateMvPredAMVP()
  18. 【在华为做OD的日子】初出茅庐
  19. 记软测面试问题(1)
  20. CONCATENATE示例

热门文章

  1. 【MySQL】MySQL 8 Show innodb status 命令改变
  2. 【nexus】nexus : mac 安装 nexus
  3. 95-130-022-源码-source-基于socket的source源码分析SocketTextStreamFunction
  4. 【Flink】Flink WindowOperator大概工作流程
  5. linux线程计算,有关Linux进程与线程数目计算的问题
  6. 趋势探讨:容器会取代虚拟机吗?
  7. 新入职了一个卷王,天天加班12点!张口闭口就是性能优化,太让人崩溃……...
  8. Kafka中@KafkaListener如何动态指定多个topic
  9. 实战 RocketMQ 流量削峰,怎么能错过这一篇!
  10. 实现拷贝函数(strcpy)