还是一样,我不喜欢长篇大论,除非关乎我设计思想领域的文章。大家过来看,都是想节省时间,能用白话表达的内容,绝不长篇大论。能直接上核心代码的,绝不上混淆代码。

长期从事 .NET 工作的人都知道。.NET 的  “object null reference“ 或者“未将对象引用到对象实例”,堪称是.NET 领域的经典错误。 一个错误定位比较麻烦,另外一个容易使程序变得不太健壮。

因此,为了尽量避免此异常的出现,也使的程序变的更加健壮,在我的框架中—Bitter.Frame 框中提供了  安全扩展方法。

涉及到:Int32?,string,Int64?,Long?,DataTime?,Float?,Doubble?,Bool 等类型的转换。

Object 转 Int32?,string,Int64?,Long?,DataTime?,Float?,Doubble?,bool等 可为 NULL 值的安全转换。

Object 转 Int32,string,Int64,Long,DataTime,Float,Doubble ,bool 等 非NULL 值的安全转换。

我们知道:工欲善其事必先利其器,做项目也一样。

如果我们有这样的代码:

  1. Int32? a = null;
  2. var b = a.ToString();

上面的过程中就会出现异常:“object null reference“ 或者“未将对象引用到对象实例”,当然上述的代码很常见,单独看上面两行代码,当然很容易发现问题所在,如果 上面代码 a 接收的是一个变量,这个变量又是客户端/或者第三方或者页面传送过来的值,他们没做好控制,或者双方没有做好很好的约定,这个变量值就很有可能为 null. 那么这个错误异常就隐藏的比较深了。

那么我们避免出现这种异常,我们来做个扩展方法,代码如下

  1. /// <summary>
  2. /// 对象转string
  3. /// </summary>
  4. /// <param name="o"></param>
  5. /// <returns></returns>
  6. public static string ToSafeString(this object o)
  7. {
  8. return o.ToSafeString(string.Empty);
  9. }
  10.  
  11. public static string ToSafeString(this object o, string defaultString)
  12. {
  13. if (o.IsEmpty())
  14. {
  15. return defaultString;
  16. }
  17. return Convert.ToString(o);
  18. }

然后我们 抛弃微软的 ToString()—我暂时称之为非安全转换,我们在使用 object.ToSafeString() 来进行安全转换。

  1. Int32? a = null;
  2. var b = a.ToSafeString(“”); //这样就不会抛出异常:object null reference

现在把相关其他类型转换源码贴出来,希望能帮助大家:

  1. public static class ObjectsUtils
  2. {
  3.  
  4. /// <summary>
  5. /// 比较对象和字符"true","false"是否相同
  6. /// </summary>
  7. /// <param name="o"></param>
  8. /// <param name="defValue">默认值</param>
  9. /// <returns>返回对象和字符"true","false"的比较值(若对象o为null,则返回defValue)</returns>
  10. public static bool ToSafeBool(this object o, bool defValue)
  11. {
  12. if (o != null)
  13. {
  14. if (string.Compare(o.ToString().Trim().ToLower(), "true", true) == 0)
  15. {
  16. return true;
  17. }
  18. if (string.Compare(o.ToString().Trim().ToLower(), "false", true) == 0)
  19. {
  20. return false;
  21. }
  22. }
  23. return defValue;
  24. }
  25.  
  26. /// <summary>
  27. /// 比较对象和字符"true","false"是否相同
  28. /// </summary>
  29. /// <param name="o"></param>
  30. /// <returns>返回对象和字符"true","false"的比较值(若对象o为null,则返回null)</returns>
  31. public static bool? ToSafeBool(this object o)
  32. {
  33. if (o != null)
  34. {
  35. if (string.Compare(o.ToString().Trim().ToLower(), "true", true) == 0 || o.ToString().Trim() == "1")
  36. {
  37. return true;
  38. }
  39. if (string.Compare(o.ToString().Trim().ToLower(), "false", true) == 0 || o.ToString().Trim() == "0")
  40. {
  41. return false;
  42. }
  43. }
  44. return null;
  45. }
  46.  
  47. /// <summary>
  48. /// 将当前时间转换成时间戳
  49. /// </summary>
  50.  
  51. /// <param name="o"></param>
  52. /// <returns></returns>
  53. public static long? ToSafeDataLong(this DateTime? o)
  54. {
  55. if (!o.HasValue)
  56. {
  57. return null;
  58. }
  59. else
  60. {
  61. System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
  62. return (long)((o.Value - startTime).TotalMilliseconds);
  63. }
  64. }
  65.  
  66. /// <summary>
  67. /// 对象转时间类型
  68. /// </summary>
  69. /// <param name="o"></param>
  70. /// <param name="defValue">时间默认值</param>
  71. /// <returns>返回对象o(若o对象为null或为空,返回defValue值)</returns>
  72. public static DateTime ToSafeDateTime(this object o, DateTime defValue)
  73. {
  74. DateTime result = defValue;
  75.  
  76. if (o == null || string.IsNullOrWhiteSpace(o.ToString()))
  77. {
  78. return result;
  79. }
  80. DateTime.TryParse(o.ToString(), out result);
  81.  
  82. return result;
  83. }
  84.  
  85. /// <summary>
  86. /// 对象转时间类型
  87. /// </summary>
  88. /// <param name="o"></param>
  89. /// <returns>返回datetime类型(若不能转时间格式或参数为null为空,则返回null)</returns>
  90.  
  91. public static DateTime? ToSafeDateTime(this object o,int exactBit=1)
  92. {
  93. if (o != null && !string.IsNullOrWhiteSpace(o.ToString()))
  94. {
  95. DateTime result;
  96. if (DateTime.TryParse(o.ToString(), out result))
  97. return result;
  98. else return null;
  99. }
  100. return null;
  101. }
  102.  
  103. /// <summary>
  104. /// 对象转时间类型
  105. /// </summary>
  106. /// <param name="o"></param>
  107. /// <returns>返回datetime类型(若不能转时间格式或参数为null为空,则返回null)</returns>
  108. public static DateTime? ToSafeDateTime(this object o)
  109. {
  110. if (o != null && !string.IsNullOrWhiteSpace(o.ToString()))
  111. {
  112. DateTime result;
  113. if (DateTime.TryParse(o.ToString(), out result))
  114. return result;
  115. else return null;
  116. }
  117. return null;
  118. }
  119.  
  120. /// <summary>
  121. /// 对象转decimal
  122. /// </summary>
  123. /// <param name="o"></param>
  124. /// <param name="defValue">默认返回值</param>
  125. /// <returns>返回decimal(若对象为null或超过30长度,则返回默认defvalue)</returns>
  126. public static decimal ToSafeDecimal(this object o, decimal defValue)
  127. {
  128. if ((o == null) || (o.ToString().Length > 30))
  129. {
  130. return defValue;
  131. }
  132. decimal result = defValue;
  133. if ((o != null) && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  134. {
  135. decimal.TryParse(o.ToString(), out result);
  136. }
  137. return result;
  138. }
  139.  
  140. public static decimal? ToSafeDecimal(this object o)
  141. {
  142. if (o != null && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  143. {
  144. decimal result;
  145. decimal.TryParse(o.ToString().Trim(), out result);
  146. return result;
  147. }
  148. return null;
  149. }
  150.  
  151. /// <summary>
  152. /// 对象转float
  153. /// </summary>
  154. /// <param name="o"></param>
  155. /// <param name="defValue">默认返回值</param>
  156. /// <returns>返回float(若对象为null或超过10长度,则返回默认defvalue)</returns>
  157. public static float ToSafeFloat(this object o, float defValue)
  158. {
  159. if ((o == null) || (o.ToString().Length > 10))
  160. {
  161. return defValue;
  162. }
  163. float result = defValue;
  164. if ((o != null) && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  165. {
  166. float.TryParse(o.ToString(), out result);
  167. }
  168. return result;
  169. }
  170.  
  171. public static float? ToSafeFloat(this object o)
  172. {
  173. if (o != null && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  174. {
  175. float result;
  176. float.TryParse(o.ToString().Trim(), out result);
  177. return result;
  178. }
  179. return null;
  180. }
  181.  
  182. /// <summary>
  183. /// 对象转int
  184. /// </summary>
  185. /// <param name="o"></param>
  186. /// <param name="defaultValue">默认返回值</param>
  187. /// <returns>返回int(若对象o为null,或对象无法转int,则返回defaultValue,字符"true"返回1,字符"false"返回0)</returns>
  188. public static int ToSafeInt32(this object o, int defaultValue)
  189. {
  190. if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  191. {
  192. int num;
  193. string s = o.ToString().Trim().ToLower();
  194. switch (s)
  195. {
  196. case "true":
  197. return 1;
  198.  
  199. case "false":
  200. return 0;
  201. }
  202. if (int.TryParse(s, out num))
  203. {
  204. return num;
  205. }
  206. }
  207. return defaultValue;
  208. }
  209.  
  210. public static int? ToSafeInt32(this object o)
  211. {
  212. if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  213. {
  214. int num;
  215. string s = o.ToString().Trim().ToLower();
  216. switch (s)
  217. {
  218. case "true":
  219. return 1;
  220.  
  221. case "false":
  222. return 0;
  223. }
  224. if (int.TryParse(s, out num))
  225. {
  226. return num;
  227. }
  228. }
  229. return null;
  230. }
  231.  
  232. /// <summary>
  233. /// 对象转Int64(long类型)
  234. /// </summary>
  235. /// <param name="o"></param>
  236. /// <param name="defaultValue"></param>
  237. /// <returns></returns>
  238. public static long ToSafeInt64(this object o, int defaultValue)
  239. {
  240. if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  241. {
  242. long num;
  243. string s = o.ToString().Trim().ToLower();
  244. switch (s)
  245. {
  246. case "true":
  247. return 1;
  248.  
  249. case "false":
  250. return 0;
  251. }
  252. if (long.TryParse(s, out num))
  253. {
  254. return num;
  255. }
  256. }
  257. return defaultValue;
  258. }
  259.  
  260. public static long? ToSafeInt64(this object o)
  261. {
  262. if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
  263. {
  264. long num;
  265. string s = o.ToString().Trim().ToLower();
  266. switch (s)
  267. {
  268. case "true":
  269. return 1;
  270.  
  271. case "false":
  272. return 0;
  273. }
  274. if (long.TryParse(s, out num))
  275. {
  276. return num;
  277. }
  278. }
  279. return null;
  280. }
  281.  
  282. /// <summary>
  283. /// 将当前时间转换成时间戳
  284. /// </summary>
  285. /// <param name="o"></param>
  286. /// <returns></returns>
  287. public static DateTime? ToSafeLongDataTime(this long? o)
  288. {
  289. if (!o.HasValue)
  290. {
  291. return null;
  292. }
  293. else if (o.Value == 0)
  294. {
  295. return null;
  296. }
  297. else
  298. {
  299. System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
  300. return (startTime.AddMilliseconds(o.Value));
  301. }
  302. }
  303.  
  304. /// <summary>
  305. /// 对象转string
  306. /// </summary>
  307. /// <param name="o"></param>
  308. /// <returns></returns>
  309. public static string ToSafeString(this object o)
  310. {
  311. return o.ToSafeString(string.Empty);
  312. }
  313.  
  314. public static string ToSafeString(this object o, string defaultString)
  315. {
  316. if (o.IsEmpty())
  317. {
  318. return defaultString;
  319. }
  320. return Convert.ToString(o);
  321. }
  322.  
  323. /// <summary>
  324. /// 将字符串转换成全角
  325. /// </summary>
  326. /// <param name="o">当前字符串</param>
  327. /// <returns></returns>
  328. public static string ToSafeSBC(this string o)
  329. {
  330. if (string.IsNullOrEmpty(o))
  331. {
  332. return o;
  333. }
  334. else
  335. {
  336. char[] cc = o.ToCharArray();
  337. for (int i = 0; i < cc.Length; i++)
  338. {
  339. if (cc[i] == 32)
  340. {
  341. // 表示空格
  342. cc[i] = (char)12288;
  343. continue;
  344. }
  345. if (cc[i] < 127 && cc[i] > 32)
  346. {
  347. cc[i] = (char)(cc[i] + 65248);
  348. }
  349. }
  350. return new string(cc);
  351. }
  352. }
  353.  
  354. /// <summary>
  355. /// 将字符串转换成半角
  356. /// </summary>
  357. /// <param name="o">当前字符串</param>
  358. /// <returns></returns>
  359. public static string ToSafeDBC(this string o)
  360. {
  361. if (string.IsNullOrEmpty(o))
  362. {
  363. return o;
  364. }
  365. else
  366. {
  367. char[] cc = o.ToCharArray();
  368. for (int i = 0; i < cc.Length; i++)
  369. {
  370. if (cc[i] == 12288)
  371. {
  372. // 表示空格
  373. cc[i] = (char)32;
  374. continue;
  375. }
  376. if (cc[i] > 65280 && cc[i] < 65375)
  377. {
  378. cc[i] = (char)(cc[i] - 65248);
  379. }
  380.  
  381. }
  382. return new string(cc);
  383. }
  384. }
  385.  
  386. /// <summary>
  387. /// 判断对象是否为空
  388. /// </summary>
  389. /// <param name="o"></param>
  390. /// <returns></returns>
  391. private static bool IsEmpty(this object o)
  392. {
  393. return ((o == null) || ((o == DBNull.Value) || Convert.IsDBNull(o)));
  394. }
  395. }

抛弃 .NET 经典错误:object null reference , 使用安全扩展方法? 希望对大家有帮助---Bitter.Frame 引用类型的安全转换的更多相关文章

  1. IE10 下系统出现Unable to get property 'PageRequestManager' of undefined or null reference错误

    在本地调试时没有任何问题,上传到测试服务器(win2003 framework 4.0)后打开网站出现Unable to get property 'PageRequestManager' of un ...

  2. 【Unity3D】中的空引用 Null Reference Exception

    Null Reference Exception : Object reference not set to an instance of an object. 异常:空引用,对象的引用未设置到对象的 ...

  3. SharePoint 2013 Error - TypeError: Unable to get property 'replace' of undefined or null reference

    错误信息 TypeError: Unable to get property ‘replace’ of undefined or null referenceTypeError: Unable to ...

  4. C#socket通讯两个最经典错误解决方案

    1.经典错误之 无法访问已释放的对象. 对象名:“System.Net.Sockets.Socket”     (1).问题现场   (2).问题叙述 程序中的某个地方调用到了socket.close ...

  5. 对象数组的初始化:null reference

    今天写代码的时候,发现我写的对象数组,只声明,而没有初始化,所以记录一下这个问题:null reference. Animals [] an=new Animals[5];//这只是个对象类型数组的声 ...

  6. Python编程的10个经典错误及解决办法

    接触了很多Python爱好者,有初学者,亦有转行人.不论大家学习Python的目的是什么,总之,学习Python前期写出来的代码不报错就是极好的.下面,严小样儿为大家罗列出Python3十大经典错误及 ...

  7. iOS开发——项目实战总结&经典错误一

    经典错误一 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv7, VA 运行报错 出现的原因:armv7s ...

  8. iOS----------常见经典错误

    最近使用cocoapods集成友盟  发现几个经典错误 1.clang: error: linker command failed with exit code 1 (use -v to see in ...

  9. 10 个 MySQL 经典错误【转】

    Top 1:Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行) 问题还原 mysql> show variables like '%max_connec ...

随机推荐

  1. (三)、vim的移动(旋转,跳跃)

    一.以word为单位的移动 1.w 向后移动到后一个单词词头,取自"word" This is a line with example text ----->--->- ...

  2. java 合并两个list 并去重

    //两个list合并并去除重复 public static void main(String[] args) throws Exception { List list1 =new ArrayList( ...

  3. 这4种ThreadLocal你都知道吗?

    什么是ThreadLocal ThreadLocal类顾名思义可以理解为线程本地变量.也就是说如果定义了一个ThreadLocal, 每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会 ...

  4. 在mac上使用vscode创建第一个C++项目

    https://blog.csdn.net/bujidexinq/article/details/106539523 准备工作:安装好vscode安装插件『C/C++』正式开始:首先是创建一个空的文件 ...

  5. C#—连接SQLserver数据库,并执行查询语句代码

    //字段ArticleID,ArticleName,ArticleNumber,Unit,Weight,Price,Currency,IsIuggage,IsQuarantine string str ...

  6. JDBC数据连接之增删改查MVC

    每天叫醒自己的不是闹钟,而是梦想 conn层 package conn; import java.sql.Connection; import java.sql.DriverManager; impo ...

  7. Putty或MobaXTerm无法连接VMware虚拟机 报Network error: Connection timed out的解决方案

    当出现无法连接的问题时, 我们要先对可能出现的问题进行梳理, 然后进行排查, 以下我先整理一些可能出现问题的地方: 1. 通过 ping 查看两台终端是否均有联网 windows下通过控制台 cmd ...

  8. 将WCF迁移到gRPC

    使用protobuf-net.Grpc将WCF服务迁移到gRPC非常简单.在这篇博文中,我们将看看它到底有多简单.微软关于将WCF服务迁移到gRPC的官方指南只提到了Gooogle.Protobuf方 ...

  9. 【递归】P1706全排列问题

    题目相关 题目描述 输出自然数 1 到 n所有不重复的排列,即 n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入格式 一个整数 n**. 输出格式 由 1∼n 组成的所有不重复的数字 ...

  10. 【Flutter】容器类组件简介

    前言 容器类Widget和布局类Widget都作用于其子Widget,不同的是: 布局类Widget一般都需要接收一个widget数组(children),他们直接或间接继承自(或包含)MultiCh ...