抛弃 .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 引用类型的安全转换

上一篇:a href标签下载文件遇到下载失败 打开文件的问题


下一篇:webp图像格式