抛弃 .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 ...
随机推荐
- MySQL误删除用户怎么解决
前言:在不考虑到原来用户对关联数据库的授权问题的情况下,有以下两种思路解决 #1.安全模式修改 第一步:关闭数据库服务: [root@db01 ~]#/etc/init.d/mysqld stop 第 ...
- vue结合element-ui table本地分页
<template> <el-table :data="tableData1.slice((start1-1)*length1,start1*length1)" ...
- Linux嵌入式学习-网络配置-ping外网、主机和域名
之前用的nfs挂载的文件系统,今天用yaffs2制作的文件系统并写入到nandflash中.但是网络却无法使用了. 首先,我们配置网卡. ifconfig eth0 192.168.1.230 bro ...
- 在 ASP.NET Core和Worker Service中使用Quartz.Net
现在有了一个官方包Quartz.Extensions.Hosting实现使用Quartz.Net运行后台任务,所以把Quartz.Net添加到ASP.NET Core或Worker Service要简 ...
- MongoDb学习三(spring-data-mongodb)
本文采用2个种配置方式.xml配置 代码配置方式进行数据库的连接.实现简单的增删该查等一些操作.代码都有注释官方文档如下https://docs.spring.io/spring-data/mongo ...
- Centos7 编译安装PHP7.2
yum install wget 在 /usr/local/src 目录下载php源码包 wget http://cn2.php.net/distributions/php-7.2.4.tar.gz ...
- SQL Server 数据库还原进度查看
SQL Server 数据库还原进度查看 关键字:数据库,还原,进度,查看 文档说明: 本文档受某实际需求启发,某约500G大小数据库还原,由于对应服务器性能较差(内存仅4G且可用内存仅2.8G),数 ...
- SparkSql自定义数据源之读取的实现
一.sparksql读取数据源的过程 1.spark目前支持读取jdbc,hive,text,orc等类型的数据,如果要想支持hbase或者其他数据源,就必须自定义 2.读取过程 (1)sparksq ...
- AI算法测评事项
前言 注:大概2017年-2018年国内人工智能热度达到顶峰,随后热度开始逐渐减少.2018年前人工智能被投资界.学术界.工业界和媒体炒的特别热,各大企业都想尝试一下深度学习技术在业务场景的应用.试水 ...
- 风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...