抛弃 .NET 经典错误:object null reference , 使用安全扩展方法? 希望对大家有帮助---Bitter.Frame 引用类型的安全转换
还是一样,我不喜欢长篇大论,除非关乎我设计思想领域的文章。大家过来看,都是想节省时间,能用白话表达的内容,绝不长篇大论。能直接上核心代码的,绝不上混淆代码。
长期从事 .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 值的安全转换。
我们知道:工欲善其事必先利其器,做项目也一样。
如果我们有这样的代码:
- Int32? a = null;
- var b = a.ToString();
上面的过程中就会出现异常:“object null reference“ 或者“未将对象引用到对象实例”,当然上述的代码很常见,单独看上面两行代码,当然很容易发现问题所在,如果 上面代码 a 接收的是一个变量,这个变量又是客户端/或者第三方或者页面传送过来的值,他们没做好控制,或者双方没有做好很好的约定,这个变量值就很有可能为 null. 那么这个错误异常就隐藏的比较深了。
那么我们避免出现这种异常,我们来做个扩展方法,代码如下
- /// <summary>
- /// 对象转string
- /// </summary>
- /// <param name="o"></param>
- /// <returns></returns>
- public static string ToSafeString(this object o)
- {
- return o.ToSafeString(string.Empty);
- }
- public static string ToSafeString(this object o, string defaultString)
- {
- if (o.IsEmpty())
- {
- return defaultString;
- }
- return Convert.ToString(o);
- }
然后我们 抛弃微软的 ToString()—我暂时称之为非安全转换,我们在使用 object.ToSafeString() 来进行安全转换。
- Int32? a = null;
- var b = a.ToSafeString(“”); //这样就不会抛出异常:object null reference
现在把相关其他类型转换源码贴出来,希望能帮助大家:
- public static class ObjectsUtils
- {
- /// <summary>
- /// 比较对象和字符"true","false"是否相同
- /// </summary>
- /// <param name="o"></param>
- /// <param name="defValue">默认值</param>
- /// <returns>返回对象和字符"true","false"的比较值(若对象o为null,则返回defValue)</returns>
- public static bool ToSafeBool(this object o, bool defValue)
- {
- if (o != null)
- {
- if (string.Compare(o.ToString().Trim().ToLower(), "true", true) == 0)
- {
- return true;
- }
- if (string.Compare(o.ToString().Trim().ToLower(), "false", true) == 0)
- {
- return false;
- }
- }
- return defValue;
- }
- /// <summary>
- /// 比较对象和字符"true","false"是否相同
- /// </summary>
- /// <param name="o"></param>
- /// <returns>返回对象和字符"true","false"的比较值(若对象o为null,则返回null)</returns>
- public static bool? ToSafeBool(this object o)
- {
- if (o != null)
- {
- if (string.Compare(o.ToString().Trim().ToLower(), "true", true) == 0 || o.ToString().Trim() == "1")
- {
- return true;
- }
- if (string.Compare(o.ToString().Trim().ToLower(), "false", true) == 0 || o.ToString().Trim() == "0")
- {
- return false;
- }
- }
- return null;
- }
- /// <summary>
- /// 将当前时间转换成时间戳
- /// </summary>
- /// <param name="o"></param>
- /// <returns></returns>
- public static long? ToSafeDataLong(this DateTime? o)
- {
- if (!o.HasValue)
- {
- return null;
- }
- else
- {
- System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
- return (long)((o.Value - startTime).TotalMilliseconds);
- }
- }
- /// <summary>
- /// 对象转时间类型
- /// </summary>
- /// <param name="o"></param>
- /// <param name="defValue">时间默认值</param>
- /// <returns>返回对象o(若o对象为null或为空,返回defValue值)</returns>
- public static DateTime ToSafeDateTime(this object o, DateTime defValue)
- {
- DateTime result = defValue;
- if (o == null || string.IsNullOrWhiteSpace(o.ToString()))
- {
- return result;
- }
- DateTime.TryParse(o.ToString(), out result);
- return result;
- }
- /// <summary>
- /// 对象转时间类型
- /// </summary>
- /// <param name="o"></param>
- /// <returns>返回datetime类型(若不能转时间格式或参数为null为空,则返回null)</returns>
- public static DateTime? ToSafeDateTime(this object o,int exactBit=1)
- {
- if (o != null && !string.IsNullOrWhiteSpace(o.ToString()))
- {
- DateTime result;
- if (DateTime.TryParse(o.ToString(), out result))
- return result;
- else return null;
- }
- return null;
- }
- /// <summary>
- /// 对象转时间类型
- /// </summary>
- /// <param name="o"></param>
- /// <returns>返回datetime类型(若不能转时间格式或参数为null为空,则返回null)</returns>
- public static DateTime? ToSafeDateTime(this object o)
- {
- if (o != null && !string.IsNullOrWhiteSpace(o.ToString()))
- {
- DateTime result;
- if (DateTime.TryParse(o.ToString(), out result))
- return result;
- else return null;
- }
- return null;
- }
- /// <summary>
- /// 对象转decimal
- /// </summary>
- /// <param name="o"></param>
- /// <param name="defValue">默认返回值</param>
- /// <returns>返回decimal(若对象为null或超过30长度,则返回默认defvalue)</returns>
- public static decimal ToSafeDecimal(this object o, decimal defValue)
- {
- if ((o == null) || (o.ToString().Length > 30))
- {
- return defValue;
- }
- decimal result = defValue;
- if ((o != null) && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- decimal.TryParse(o.ToString(), out result);
- }
- return result;
- }
- public static decimal? ToSafeDecimal(this object o)
- {
- if (o != null && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- decimal result;
- decimal.TryParse(o.ToString().Trim(), out result);
- return result;
- }
- return null;
- }
- /// <summary>
- /// 对象转float
- /// </summary>
- /// <param name="o"></param>
- /// <param name="defValue">默认返回值</param>
- /// <returns>返回float(若对象为null或超过10长度,则返回默认defvalue)</returns>
- public static float ToSafeFloat(this object o, float defValue)
- {
- if ((o == null) || (o.ToString().Length > 10))
- {
- return defValue;
- }
- float result = defValue;
- if ((o != null) && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- float.TryParse(o.ToString(), out result);
- }
- return result;
- }
- public static float? ToSafeFloat(this object o)
- {
- if (o != null && Regex.IsMatch(o.ToString(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- float result;
- float.TryParse(o.ToString().Trim(), out result);
- return result;
- }
- return null;
- }
- /// <summary>
- /// 对象转int
- /// </summary>
- /// <param name="o"></param>
- /// <param name="defaultValue">默认返回值</param>
- /// <returns>返回int(若对象o为null,或对象无法转int,则返回defaultValue,字符"true"返回1,字符"false"返回0)</returns>
- public static int ToSafeInt32(this object o, int defaultValue)
- {
- if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- int num;
- string s = o.ToString().Trim().ToLower();
- switch (s)
- {
- case "true":
- return 1;
- case "false":
- return 0;
- }
- if (int.TryParse(s, out num))
- {
- return num;
- }
- }
- return defaultValue;
- }
- public static int? ToSafeInt32(this object o)
- {
- if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- int num;
- string s = o.ToString().Trim().ToLower();
- switch (s)
- {
- case "true":
- return 1;
- case "false":
- return 0;
- }
- if (int.TryParse(s, out num))
- {
- return num;
- }
- }
- return null;
- }
- /// <summary>
- /// 对象转Int64(long类型)
- /// </summary>
- /// <param name="o"></param>
- /// <param name="defaultValue"></param>
- /// <returns></returns>
- public static long ToSafeInt64(this object o, int defaultValue)
- {
- if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- long num;
- string s = o.ToString().Trim().ToLower();
- switch (s)
- {
- case "true":
- return 1;
- case "false":
- return 0;
- }
- if (long.TryParse(s, out num))
- {
- return num;
- }
- }
- return defaultValue;
- }
- public static long? ToSafeInt64(this object o)
- {
- if ((o != null) && !string.IsNullOrEmpty(o.ToString()) && Regex.IsMatch(o.ToString().Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$"))
- {
- long num;
- string s = o.ToString().Trim().ToLower();
- switch (s)
- {
- case "true":
- return 1;
- case "false":
- return 0;
- }
- if (long.TryParse(s, out num))
- {
- return num;
- }
- }
- return null;
- }
- /// <summary>
- /// 将当前时间转换成时间戳
- /// </summary>
- /// <param name="o"></param>
- /// <returns></returns>
- public static DateTime? ToSafeLongDataTime(this long? o)
- {
- if (!o.HasValue)
- {
- return null;
- }
- else if (o.Value == 0)
- {
- return null;
- }
- else
- {
- System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
- return (startTime.AddMilliseconds(o.Value));
- }
- }
- /// <summary>
- /// 对象转string
- /// </summary>
- /// <param name="o"></param>
- /// <returns></returns>
- public static string ToSafeString(this object o)
- {
- return o.ToSafeString(string.Empty);
- }
- public static string ToSafeString(this object o, string defaultString)
- {
- if (o.IsEmpty())
- {
- return defaultString;
- }
- return Convert.ToString(o);
- }
- /// <summary>
- /// 将字符串转换成全角
- /// </summary>
- /// <param name="o">当前字符串</param>
- /// <returns></returns>
- public static string ToSafeSBC(this string o)
- {
- if (string.IsNullOrEmpty(o))
- {
- return o;
- }
- else
- {
- char[] cc = o.ToCharArray();
- for (int i = 0; i < cc.Length; i++)
- {
- if (cc[i] == 32)
- {
- // 表示空格
- cc[i] = (char)12288;
- continue;
- }
- if (cc[i] < 127 && cc[i] > 32)
- {
- cc[i] = (char)(cc[i] + 65248);
- }
- }
- return new string(cc);
- }
- }
- /// <summary>
- /// 将字符串转换成半角
- /// </summary>
- /// <param name="o">当前字符串</param>
- /// <returns></returns>
- public static string ToSafeDBC(this string o)
- {
- if (string.IsNullOrEmpty(o))
- {
- return o;
- }
- else
- {
- char[] cc = o.ToCharArray();
- for (int i = 0; i < cc.Length; i++)
- {
- if (cc[i] == 12288)
- {
- // 表示空格
- cc[i] = (char)32;
- continue;
- }
- if (cc[i] > 65280 && cc[i] < 65375)
- {
- cc[i] = (char)(cc[i] - 65248);
- }
- }
- return new string(cc);
- }
- }
- /// <summary>
- /// 判断对象是否为空
- /// </summary>
- /// <param name="o"></param>
- /// <returns></returns>
- private static bool IsEmpty(this object o)
- {
- return ((o == null) || ((o == DBNull.Value) || Convert.IsDBNull(o)));
- }
- }
抛弃 .NET 经典错误:object null reference , 使用安全扩展方法? 希望对大家有帮助---Bitter.Frame 引用类型的安全转换的更多相关文章
- IE10 下系统出现Unable to get property 'PageRequestManager' of undefined or null reference错误
在本地调试时没有任何问题,上传到测试服务器(win2003 framework 4.0)后打开网站出现Unable to get property 'PageRequestManager' of un ...
- 【Unity3D】中的空引用 Null Reference Exception
Null Reference Exception : Object reference not set to an instance of an object. 异常:空引用,对象的引用未设置到对象的 ...
- 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 ...
- C#socket通讯两个最经典错误解决方案
1.经典错误之 无法访问已释放的对象. 对象名:“System.Net.Sockets.Socket” (1).问题现场 (2).问题叙述 程序中的某个地方调用到了socket.close ...
- 对象数组的初始化:null reference
今天写代码的时候,发现我写的对象数组,只声明,而没有初始化,所以记录一下这个问题:null reference. Animals [] an=new Animals[5];//这只是个对象类型数组的声 ...
- Python编程的10个经典错误及解决办法
接触了很多Python爱好者,有初学者,亦有转行人.不论大家学习Python的目的是什么,总之,学习Python前期写出来的代码不报错就是极好的.下面,严小样儿为大家罗列出Python3十大经典错误及 ...
- iOS开发——项目实战总结&经典错误一
经典错误一 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv7, VA 运行报错 出现的原因:armv7s ...
- iOS----------常见经典错误
最近使用cocoapods集成友盟 发现几个经典错误 1.clang: error: linker command failed with exit code 1 (use -v to see in ...
- 10 个 MySQL 经典错误【转】
Top 1:Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行) 问题还原 mysql> show variables like '%max_connec ...
随机推荐
- (三)、vim的移动(旋转,跳跃)
一.以word为单位的移动 1.w 向后移动到后一个单词词头,取自"word" This is a line with example text ----->--->- ...
- java 合并两个list 并去重
//两个list合并并去除重复 public static void main(String[] args) throws Exception { List list1 =new ArrayList( ...
- 这4种ThreadLocal你都知道吗?
什么是ThreadLocal ThreadLocal类顾名思义可以理解为线程本地变量.也就是说如果定义了一个ThreadLocal, 每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会 ...
- 在mac上使用vscode创建第一个C++项目
https://blog.csdn.net/bujidexinq/article/details/106539523 准备工作:安装好vscode安装插件『C/C++』正式开始:首先是创建一个空的文件 ...
- C#—连接SQLserver数据库,并执行查询语句代码
//字段ArticleID,ArticleName,ArticleNumber,Unit,Weight,Price,Currency,IsIuggage,IsQuarantine string str ...
- JDBC数据连接之增删改查MVC
每天叫醒自己的不是闹钟,而是梦想 conn层 package conn; import java.sql.Connection; import java.sql.DriverManager; impo ...
- Putty或MobaXTerm无法连接VMware虚拟机 报Network error: Connection timed out的解决方案
当出现无法连接的问题时, 我们要先对可能出现的问题进行梳理, 然后进行排查, 以下我先整理一些可能出现问题的地方: 1. 通过 ping 查看两台终端是否均有联网 windows下通过控制台 cmd ...
- 将WCF迁移到gRPC
使用protobuf-net.Grpc将WCF服务迁移到gRPC非常简单.在这篇博文中,我们将看看它到底有多简单.微软关于将WCF服务迁移到gRPC的官方指南只提到了Gooogle.Protobuf方 ...
- 【递归】P1706全排列问题
题目相关 题目描述 输出自然数 1 到 n所有不重复的排列,即 n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入格式 一个整数 n**. 输出格式 由 1∼n 组成的所有不重复的数字 ...
- 【Flutter】容器类组件简介
前言 容器类Widget和布局类Widget都作用于其子Widget,不同的是: 布局类Widget一般都需要接收一个widget数组(children),他们直接或间接继承自(或包含)MultiCh ...