using MWS.Library.Common.Module;
using MWS.Library.Enums;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;

namespace MWS.Library.Common
{
    public static class TypeExtension
    {
        public static T Copy<T>(this T obj) where T : class
        {
            T result;
            using (MemoryStream memoryStream = new MemoryStream())
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
                binaryFormatter.Serialize(memoryStream, obj);
                memoryStream.Seek(0L, SeekOrigin.Begin);
                T t = default(T);
                try
                {
                    t = (T)binaryFormatter.Deserialize(memoryStream);
                }
                catch (Exception exception)
                {
                    LogHelper.WriteLog("深拷贝对象失败", exception);
                }
                result = t;
            }
            return result;
        }

        public static string GetPropertyName<T>(this Expression<Func<T, object>> expr)
        {
            return ((MemberExpression)expr.Body).Member.Name;
        }

        private static object Copy1(this object obj)
        {
            Type type = obj.GetType();
            object obj2;
            if (type.IsValueType)
            {
                obj2 = obj;
            }
            else
            {
                obj2 = Activator.CreateInstance(type);
                MemberInfo[] members = obj.GetType().GetMembers();
                foreach (MemberInfo memberInfo in members)
                {
                    if (memberInfo.MemberType == MemberTypes.Field)
                    {
                        FieldInfo fieldInfo = (FieldInfo)memberInfo;
                        object value = fieldInfo.GetValue(obj);
                        if (value is ICloneable)
                        {
                            fieldInfo.SetValue(obj2, (value as ICloneable).Clone());
                        }
                        else
                        {
                            fieldInfo.SetValue(obj2, value.Copy());
                        }
                    }
                    else if (memberInfo.MemberType == MemberTypes.Property)
                    {
                        PropertyInfo propertyInfo = (PropertyInfo)memberInfo;
                        MethodInfo setMethod = propertyInfo.GetSetMethod(false);
                        if (setMethod != null)
                        {
                            object value2 = propertyInfo.GetValue(obj, null);
                            if (value2 is ICloneable)
                            {
                                propertyInfo.SetValue(obj2, (value2 as ICloneable).Clone(), null);
                            }
                            else
                            {
                                propertyInfo.SetValue(obj2, value2.Copy(), null);
                            }
                        }
                    }
                }
            }
            return obj2;
        }

        public static void Append(this Stream stream, Stream descSream)
        {
            byte[] array = new byte[descSream.Length];
            descSream.Read(array, 0, array.Length);
            descSream.Seek(0L, SeekOrigin.Begin);
            stream.Write(array, 0, array.Length);
        }

        public static string GetSafeAttributeValue(this XmlNode node, string attribute)
        {
            string result;
            if (node == null)
            {
                result = string.Empty;
            }
            else if (node.Attributes != null)
            {
                XmlAttribute xmlAttribute = node.Attributes[attribute];
                if (xmlAttribute == null)
                {
                    result = string.Empty;
                }
                else
                {
                    result = xmlAttribute.Value.Trim();
                }
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static TEnum GetSafeAttributeEnum<TEnum>(this XmlNode node, string attribute, TEnum defaultValue)
        {
            try
            {
                string safeAttributeValue = node.GetSafeAttributeValue(attribute);
                if (safeAttributeValue.IsValid())
                {
                    return safeAttributeValue.Replace("，", ",").ToEnum<TEnum>();
                }
            }
            catch
            {
            }
            return defaultValue;
        }

        public static bool IsValid(this Version value)
        {
            return !(value == null) && (value.Major > 0 || value.Minor > 0 || value.Build > 0 || value.Revision > 0);
        }

        public static Version ToSafeVersion(this string value)
        {
            Version version = new Version();
            Version result;
            if (value.IsInvalid())
            {
                result = version;
            }
            else if (Version.TryParse(value, out version))
            {
                result = version;
            }
            else
            {
                MatchCollection matchCollection = Regex.Matches(value, "(\\d{1,8}\\.){1,3}\\d{1,8}", RegexOptions.IgnoreCase);
                if (matchCollection.Count == 0)
                {
                    result = version;
                }
                else
                {
                    result = matchCollection[0].ToSafeString().ToSafeVersion();
                }
            }
            return result;
        }

        public static string ToShortString(this Version value)
        {
            string result;
            if (!value.IsValid())
            {
                result = string.Empty;
            }
            else if (value.Minor <= 0 && value.Build <= 0 && value.Revision <= 0)
            {
                result = string.Format("{0}", value.Major);
            }
            else if (value.Build <= 0 && value.Revision <= 0)
            {
                result = string.Format("{0}.{1}", value.Major, value.Minor);
            }
            else if (value.Revision <= 0)
            {
                result = string.Format("{0}.{1}.{2}", value.Major, value.Minor, value.Build);
            }
            else
            {
                result = string.Format("{0}.{1}.{2}.{3}", new object[]
                {
                    value.Major,
                    value.Minor,
                    value.Build,
                    value.Revision
                });
            }
            return result;
        }

        public static void AppendKeyValueNewLine(this StringBuilder sb, string key, object value)
        {
            if (value != null && !value.ToString().IsInvalid())
            {
                sb.Append(key).Append("：").Append(value).Append(Environment.NewLine);
            }
        }

        public static void AppendKeyValueNewLine(this StringBuilder sb, string key, Enum value)
        {
            sb.Append(key).Append("：").Append(value.GetDescription()).Append(Environment.NewLine);
        }

        public static void AppendKeyValue(this StringBuilder builder, string key, object value, string end = " ")
        {
            if (value != null && !value.ToString().IsInvalid())
            {
                builder.AppendFormat("{0}：{1}{2}", key, value, end);
            }
        }

        public static void AppendKeyValue(this StringBuilder sb, string key, Enum value, string end = " ")
        {
            sb.Append(key).Append("：").Append(value.GetDescription()).Append(end);
        }

        public static IQueryable<T> WhereIf<T>(this IQueryable<T> @this, Expression<Func<T, bool>> predicate, bool condition)
        {
            return condition ? @this.Where(predicate) : @this;
        }

        public static bool ToBoolean(this string value)
        {
            if (bool.TryParse(value, out bool result))
            {
                return result;
            }
            throw new InvalidCastException("\"" + value + "\"不是有效的boolean，请确认。");
        }

        public static bool ToSafeBoolean(this string value, bool defaultValue = false)
        {
            bool result;
            if (bool.TryParse(value, out bool flag))
            {
                result = flag;
            }
            else
            {
                result = defaultValue;
            }
            return result;
        }

        public static string ToCNString(this bool value)
        {
            return value ? "是" : "否";
        }

        public static string ToCNString(this bool? value)
        {
            return (value != null) ? value.ToString() : string.Empty;
        }

        public static string GetString(this byte[] bytes, Encoding encode)
        {
            string result;
            if (bytes == null || bytes.Count<byte>() <= 0)
            {
                result = string.Empty;
            }
            else
            {
                result = encode.GetString(bytes);
            }
            return result;
        }

        public static string GetString(this byte[] bytes)
        {
            return bytes.GetString(Encoding.Default);
        }

        public static string ToBinary(this byte value)
        {
            return Convert.ToString(value, 2);
        }

        public static string ToBinary(this byte[] values, string separator = " ")
        {
            string result;
            if (values == null || values.Length <= 0)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (byte value in values)
                {
                    stringBuilder.Append(value.ToBinary()).Append(separator);
                }
                result = stringBuilder.ToString();
            }
            return result;
        }


        public static string To16Bland(this byte value)
        {
            return value.ToString("X2");
        }

        public static byte[] ObjectToBinary(object request)
        {
            BinaryFormatter serializer = new BinaryFormatter();
            MemoryStream memStream = new MemoryStream();
            serializer.Serialize(memStream, request);
            return memStream.GetBuffer();
        }

        public static object BinaryToObject(byte[] bufer)
        {
            MemoryStream memStream = new MemoryStream(bufer);
            memStream.Position = 0;
            BinaryFormatter deserializer = new BinaryFormatter();
            object newobj = deserializer.Deserialize(memStream);
            memStream.Close();
            return newobj;
        }
        public static string To16Bland(this byte[] values, string separator = " ")
        {
            string result;
            if (values == null || values.Length <= 0)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (byte value in values)
                {
                    stringBuilder.Append(value.To16Bland()).Append(separator);
                }
                result = stringBuilder.ToString();
            }
            return result;
        }

        public static Dictionary<string, string> ToDictionaryH(this HttpContext context)
        {
            Dictionary<string, string> result;
            if (context == null || context.Request == null)
            {
                result = new Dictionary<string, string>();
            }
            else
            {
                string httpMethod = context.Request.HttpMethod;
                NameValueCollection nameValueCollection = new NameValueCollection();
                if (httpMethod.Equals(EnumHttpMode.Post.GetDescription()))
                {
                    nameValueCollection = context.Request.Form;
                }
                else if (httpMethod.Equals(EnumHttpMode.Get.GetDescription()))
                {
                    nameValueCollection = context.Request.QueryString;
                }
                Dictionary<string, string> dictionary = new Dictionary<string, string>();
                if (nameValueCollection != null && nameValueCollection.Count > 0)
                {
                    foreach (object obj in nameValueCollection)
                    {
                        string text = (string)obj;
                        dictionary.Add(text, nameValueCollection[text]);
                    }
                }
                result = dictionary;
            }
            return result;
        }

        public static TValue GetSafeValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defalut = default(TValue))
        {
            TValue result;
            if (dictionary.IsInvalid())
            {
                result = defalut;
            }
            else if (dictionary.ContainsKey(key))
            {
                result = dictionary[key];
            }
            else
            {
                result = defalut;
            }
            return result;
        }

        // Token: 0x060001A9 RID: 425 RVA: 0x00008A4C File Offset: 0x00006C4C
        public static bool IsBetween<T>(this T @this, T lower, T upper, bool includeLower = true, bool includeUpper = true) where T : IComparable<T>
        {
            bool result;
            if (@this == null)
            {
                result = false;
            }
            else
            {
                int num = @this.CompareTo(lower);
                int num2 = @this.CompareTo(upper);
                result = ((includeLower && num == 0) || (includeUpper && num2 == 0) || (num > 0 && num2 < 0));
            }
            return result;
        }

        public static bool IsBetween<T>(this T @this, T lower, T upper, IComparer<T> comparer, bool includeLower = true, bool includeUpper = true)
        {
            bool result;
            if (@this == null)
            {
                result = false;
            }
            else
            {
                int num = comparer.Compare(@this, lower);
                int num2 = comparer.Compare(@this, upper);
                result = ((includeLower && num == 0) || (includeUpper && num2 == 0) || (num > 0 && num2 < 0));
            }
            return result;
        }

        public static bool IsNullableType(this Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition() == Constants.NullableType;
        }

        public static Type GetNullableGenericType(this Type type)
        {
            return type.IsNullableType() ? type.GetGenericArguments()[0] : type;
        }

        public static T SafeValue<T>(this T? @this) where T : struct
        {
            return @this ?? default(T);
        }

        public static string ToDateStringFromNow(this DateTime dt)
        {
            string result;
            if (!dt.IsValid())
            {
                result = string.Empty;
            }
            else
            {
                TimeSpan timeSpan = DateTime.Now - dt;
                if (timeSpan.TotalDays > 365.0)
                {
                    result = string.Format("{0}年前", (int)Math.Floor(timeSpan.TotalDays / 365.0));
                }
                else if (timeSpan.TotalDays > 30.0)
                {
                    result = string.Format("{0}个月前", (int)Math.Floor(timeSpan.TotalDays / 30.0));
                }
                else if (timeSpan.TotalDays > 7.0)
                {
                    result = string.Format("{0}周前", (int)Math.Floor(timeSpan.TotalDays / 7.0));
                }
                else if (timeSpan.TotalDays > 1.0)
                {
                    result = string.Format("{0}天前", (int)Math.Floor(timeSpan.TotalDays));
                }
                else if (timeSpan.TotalHours > 1.0)
                {
                    result = string.Format("{0}小时前", (int)Math.Floor(timeSpan.TotalHours));
                }
                else if (timeSpan.TotalMinutes > 1.0)
                {
                    result = string.Format("{0}分钟前", (int)Math.Floor(timeSpan.TotalMinutes));
                }
                else if (timeSpan.TotalSeconds >= 1.0)
                {
                    result = string.Format("{0}秒前", (int)Math.Floor(timeSpan.TotalSeconds));
                }
                else if (dt.Date == DateTime.Now.Date)
                {
                    result = "今天";
                }
                else
                {
                    int num = (int)Math.Floor(Math.Abs((dt - DateTime.Now).TotalDays));
                    if (num == 1)
                    {
                        result = "明天";
                    }
                    else if (num == 2)
                    {
                        result = "后天";
                    }
                    else if (num < 7)
                    {
                        result = string.Format("{0}天后", num);
                    }
                    else if (num < 30)
                    {
                        result = string.Format("{0}周后", num / 7);
                    }
                    else if (num < 365)
                    {
                        result = string.Format("{0}月后", num / 30);
                    }
                    else
                    {
                        result = string.Format("{0}年后", num / 365);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public static long GetTimeStamp(DateTime? time = null)
        {
            TimeSpan ts;
            if (time != null)
            {
                ts = time.Value - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            }
            else
            {
                ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            }

            return Convert.ToInt64(ts.TotalMilliseconds);
        }

        /// <summary>
        /// 时间戳反转为时间 
        /// </summary>
        /// <param name="TimeStamp">时间戳</param>
        /// <returns>返回一个日期时间</returns>
        public static DateTime GetTime(long TimeStamp)
        {
            return new DateTime(1970, 1, 1).AddMilliseconds(TimeStamp);
        }
        public static string ToDateStringFromNow(this DateTime? dt)
        {
            string result;
            if (dt != null)
            {
                result = dt.Value.ToDateStringFromNow();
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static string FormatDateTime(this int secondTime)
        {
            string DateTimes = null;
            int days = secondTime / (60 * 60 * 24);
            int hours = (secondTime % (60 * 60 * 24)) / (60 * 60);
            int minutes = (secondTime % (60 * 60)) / 60;
            int seconds = secondTime % 60;
            if (days > 0)
            {
                DateTimes = days + "天" + hours + "小时" + minutes + "分钟" + seconds + "秒";
            }
            else if (hours > 0)
            {
                DateTimes = hours + "小时" + minutes + "分钟" + seconds + "秒";
            }
            else if (minutes > 0)
            {
                DateTimes = minutes + "分钟" + seconds + "秒";
            }
            else
            {
                DateTimes = seconds + "秒";
            }

            return DateTimes;
        }

        public static DateTime ToDateTime(this string value, string format, string culture = "zh-CHS")
        {
            if (DateTime.TryParseExact(value, format, new CultureInfo("zh-CHS"), DateTimeStyles.None, out DateTime result))
            {
                return result;
            }
            throw new Exception(string.Format("字符串（{0}）不能按照格式（{1}）解析为日期时间", value, format));
        }

        public static DateTime ToDateTime(this string dateTime)
        {
            if (DateTime.TryParse(dateTime, out DateTime result))
            {
                return result;
            }
            throw new InvalidCastException("\"" + dateTime + "\"不是有效的时间格式，请确认。");
        }

        public static DateTime? ToSafeDateTime(this string dateTime)
        {
            DateTime? result;
            if (DateTime.TryParse(dateTime, out DateTime value))
            {
                result = new DateTime?(value);
            }
            else
            {
                result = null;
            }
            return result;
        }

        public static DateTime? ToUTCTime(this string dateTime)
        {
            DateTime? dateTime2 = dateTime.ToSafeDateTime();
            DateTime? result;
            if (dateTime2 != null)
            {
                result = dateTime2;
            }
            else
            {
                Regex regex = new Regex("(?i)\\d+ [a-z]+ \\d{4} \\d+:\\d+:\\d+ [-\\+]\\d+");
                result = regex.Match(dateTime).Value.ToSafeDateTime();
            }
            return result;
        }

        public static bool IsValid(this DateTime value)
        {
            return !(DateTime.MinValue == value) && !(DateTime.MaxValue == value);
        }

        public static bool IsValid(this DateTime? value)
        {
            return value != null && !(DateTime.MinValue == value) && !(DateTime.MaxValue == value);
        }

        public static string ToDateString(this DateTime value)
        {
            return value.IsValid() ? value.ToString("yyyy-MM-dd") : string.Empty;
        }

        public static string ToDateString(this DateTime? value)
        {
            string result;
            if (value != null)
            {
                result = (value.IsValid() ? value.Value.ToString("yyyy-MM-dd") : string.Empty);
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static string ToDateString(this DateTime? value, string format, string defaultStr = "")
        {
            string result;
            if (value != null)
            {
                result = (value.IsValid() ? value.Value.ToString(format) : defaultStr);
            }
            else
            {
                result = defaultStr;
            }
            return result;
        }

        public static string ToDateTimeString(this DateTime value)
        {
            string result;
            if (!value.IsValid())
            {
                result = string.Empty;
            }
            else if (value.Hour == 0 && value.Minute == 0 && value.Second == 0)
            {
                result = value.ToDateString();
            }
            else
            {
                result = value.ToString("yyyy-MM-dd HH:mm:ss");
            }
            return result;
        }

        public static string ToDateTimeString(this DateTime? value)
        {
            string result;
            if (value.IsValid())
            {
                result = value.Value.ToDateTimeString();
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static string ToLogString(this Exception ex)
        {
            string result;
            if (ex == null)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("  >>异常消息（Message）：").AppendLine(ex.Message);
                stringBuilder.Append("  >>异常来源（Source）：").AppendLine(ex.Source);
                stringBuilder.Append("  >>异常类型（ExceptionType）：").AppendLine(ex.GetType().ToString());
                stringBuilder.Append("  >>原生异常类型（BaseExceptionType）：").AppendLine(ex.GetBaseException().GetType().ToString());
                stringBuilder.Append("  >>出错的方法签名（TargetSite）：").Append(ex.TargetSite);
                if (ex.Data.Count > 0)
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append("  >>自定义数据（Data）：");
                    StringBuilder stringBuilder2 = new StringBuilder();
                    foreach (object obj in ex.Data)
                    {
                        DictionaryEntry dictionaryEntry = (DictionaryEntry)obj;
                        stringBuilder2.Append(string.Concat(new object[]
                        {
                            "Key：",
                            dictionaryEntry.Key,
                            "，Value：",
                            dictionaryEntry.Value,
                            "; "
                        }));
                    }
                    stringBuilder.Append(stringBuilder2);
                }
                if (!string.IsNullOrEmpty(ex.StackTrace))
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append("  >>堆栈信息（StackTrace）：");
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(ex.StackTrace);
                }
                if (ex.InnerException != null)
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(">>========================== 内部异常（InnerException）==========================");
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(ex.InnerException.ToLogString());
                }
                result = stringBuilder.ToString();
            }
            return result;
        }

        public static string AllMessage(this Exception ex)
        {
            string result;
            if (ex == null)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append(ex.Message);
                if (ex.InnerException != null)
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(">").Append(ex.InnerException.AllMessage());
                }
                result = stringBuilder.ToString();
            }
            return result;
        }

        public static void ForEach<T>(this IEnumerable<T> souce, Action<T> action)
        {
            if (!souce.IsInvalid<T>())
            {
                foreach (T obj in souce)
                {
                    action(obj);
                }
            }
        }

        public static T FindFirst<T>(this IEnumerable<T> source) where T : class
        {
            T result;
            if (source.IsInvalid<T>())
            {
                result = default(T);
            }
            else
            {
                using (IEnumerator<T> enumerator = source.GetEnumerator())
                {
                    if (enumerator.MoveNext())
                    {
                        return enumerator.Current;
                    }
                }
                result = default(T);
            }
            return result;
        }

        public static object FindFirst(this IEnumerable source)
        {
            object result;
            if (source.IsInvalid())
            {
                result = null;
            }
            else
            {
                IEnumerator enumerator = source.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    return enumerator.Current;
                }
                result = null;
            }
            return result;
        }

        public static IEnumerable<Ttarget> ConvertAll<Ttarget>(this IEnumerable @this) where Ttarget : class
        {
            IEnumerable<Ttarget> result;
            if (@this == null)
            {
                result = null;
            }
            else
            {
                IEnumerable<Ttarget> enumerable = @this as IEnumerable<Ttarget>;
                if (enumerable != null)
                {
                    result = enumerable;
                }
                else
                {
                    Collection<Ttarget> collection = new Collection<Ttarget>();
                    foreach (object obj in @this)
                    {
                        Ttarget ttarget = obj as Ttarget;
                        if (ttarget == null)
                        {
                            throw new ArgumentException("invalid Target:" + typeof(Ttarget));
                        }
                        collection.Add(ttarget);
                    }
                    result = collection;
                }
            }
            return result;
        }

        public static IEnumerable<Ttarget> ConvertAllyield<Ttarget>(this IEnumerable @this) where Ttarget : class
        {
            if (@this != null)
            {
                foreach (object item in @this)
                {
                    Ttarget titem = item as Ttarget;
                    yield return titem;
                }
            }
            yield break;
        }

        public static List<T> ToList<T>(this IEnumerator<T> source)
        {
            List<T> list = new List<T>();
            List<T> result;
            if (source == null)
            {
                result = list;
            }
            else
            {
                while (source.MoveNext())
                {
                    T item = source.Current;
                    list.Add(item);
                }
                result = list;
            }
            return result;
        }

        public static bool IsValid<T>(this IEnumerable<T> source)
        {
            return source != null && source.Any<T>();
        }

        public static bool IsValid(this IEnumerable @this)
        {
            bool result;
            if (@this == null)
            {
                result = false;
            }
            else
            {
                IEnumerator enumerator = @this.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    object obj = enumerator.Current;
                    return true;
                }
                result = false;
            }
            return result;
        }

        public static bool IsInvalid<T>(this IEnumerable<T> source)
        {
            return !source.IsValid<T>();
        }

        public static bool IsInvalid(this IEnumerable @this)
        {
            return !@this.IsValid();
        }

        public static void AddRange<T>(this ICollection<T> @this, IEnumerable<T> values)
        {
            foreach (T item in values)
            {
                @this.Add(item);
            }
        }

        public static T GetSafeValue<T>(this IList<T> @this, int index, T defaultValue = default(T))
        {
            T result;
            if (@this.IsInvalid<T>())
            {
                result = defaultValue;
            }
            else if (@this.Count > index)
            {
                result = defaultValue;
            }
            else
            {
                result = @this[index];
            }
            return result;
        }

        public static byte ToSafeByte(this string value)
        {
            byte result;
            if (byte.TryParse(value, out byte b))
            {
                result = b;
            }
            else
            {
                result = 0;
            }
            return result;
        }

        public static short ToInt16(this string value)
        {
            if (short.TryParse(value, out short result))
            {
                return result;
            }
            throw new InvalidCastException("不能将字符串\"" + value + "\"转换为短整形数字。");
        }

        public static short ToSafeInt16(this string value)
        {
            short result;
            if (short.TryParse(value, out short num))
            {
                result = num;
            }
            else
            {
                result = 0;
            }
            return result;
        }

        public static int ToInt(this string value)
        {
            if (int.TryParse(value, out int result))
            {
                return result;
            }
            throw new InvalidCastException("不能将字符串\"" + value + "\"转换为整形数字。");
        }

        public static int ToSafeInt(this JToken value)
        {
            if (int.TryParse((value ?? "0").ToString(), out int result))
            {
                return result;
            }
            else
            {
                return 0;
            }
        }

        public static int ToSafeInt(this string value)
        {
            int result;
            if (value.Contains(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator))
            {
                result = (int)value.ToSafeDouble();
            }
            else if (int.TryParse(value, out int num))
            {
                result = num;
            }
            else
            {
                result = 0;
            }
            return result;
        }

        public static long ToInt64(this string value)
        {
            if (long.TryParse(value, out long result))
            {
                return result;
            }
            throw new InvalidCastException("不能将字符串\"" + value + "\"转换为长整形数字。");
        }

        public static long ToSafeInt64(this string value)
        {
            long result;
            if (value.Contains(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator))
            {
                result = (long)value.ToSafeDouble();
            }
            else if (long.TryParse(value, out long num))
            {
                result = num;
            }
            else
            {
                result = 0L;
            }
            return result;
        }

        public static ulong ToSafeUlong(this string value)
        {
            ulong result;
            if (string.IsNullOrWhiteSpace(value))
            {
                result = 0UL;
            }
            else if (value.Contains(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator))
            {
                result = (ulong)value.ToSafeDouble();
            }
            else if (ulong.TryParse(value, out ulong num))
            {
                result = num;
            }
            else
            {
                result = 0UL;
            }
            return result;
        }

        public static bool IsGreaterThanZero(this int value)
        {
            return value > 0;
        }

        public static bool IsGreaterThanZero(this int? value)
        {
            return value != null && value > 0;
        }

        public static byte ToByte(this int value)
        {
            byte result;
            try
            {
                result = BitConverter.GetBytes(value)[0];
            }
            catch
            {
                result = 0;
            }
            return result;
        }

        public static bool IsInstanceOfType(this Type instanceType, Type type)
        {
            bool result;
            if (instanceType == type)
            {
                result = true;
            }
            else
            {
                foreach (Type left in instanceType.GetInterfaces())
                {
                    if (left == type)
                    {
                        return true;
                    }
                }
                while (instanceType != Constants.ObjectType)
                {
                    if (type == instanceType)
                    {
                        return true;
                    }
                    instanceType = instanceType.BaseType;
                }
                result = false;
            }
            return result;
        }

        public static bool IsInstanceOfType(this object instance, Type type)
        {
            bool result;
            if (instance == null)
            {
                result = false;
            }
            else
            {
                Type type2 = instance.GetType();
                result = type2.IsInstanceOfType(type);
            }
            return result;
        }

        public static bool IsInstanceOfT<T>(this Type instanceType)
        {
            return instanceType.IsInstanceOfType(typeof(T));
        }

        public static bool IsInstanceOfT<T>(this object instance)
        {
            bool result;
            if (instance == null)
            {
                result = false;
            }
            else
            {
                Type type = instance.GetType();
                result = type.IsInstanceOfType(typeof(T));
            }
            return result;
        }

        public static bool IsCompatibleType(this Type type1, Type type2)
        {
            bool result;
            if (type1 == type2)
            {
                result = true;
            }
            else if (type1.IsEnum && Enum.GetUnderlyingType(type1) == type2)
            {
                result = true;
            }
            else
            {
                Type underlyingType = Nullable.GetUnderlyingType(type1);
                Type underlyingType2 = Nullable.GetUnderlyingType(type2);
                result = (underlyingType != null && underlyingType2 != null && underlyingType.IsCompatibleType(underlyingType2));
            }
            return result;
        }

        public static bool IsImplementsInterface(this Type objectType, Type interfaceType)
        {
            if (!interfaceType.IsInterface)
            {
                throw new ArgumentException(string.Format("查找类似 指定的类型{0}不是接口类型。", interfaceType.Name), "interfaceType");
            }
            Type[] interfaces = objectType.GetInterfaces();
            int i = 0;
            while (i < interfaces.Length)
            {
                Type type = interfaces[i];
                if (!(type == interfaceType))
                {
                    if (type.Name.Contains("`"))
                    {
                        if (type.Name == interfaceType.Name && type.Assembly == interfaceType.Assembly)
                        {
                            return true;
                        }
                    }
                    i++;
                    continue;
                }
                return true;
            }
            return false;
        }

        public static object GetValue(this PropertyInfo pi, object obj)
        {
            object result;
            if (pi == null || obj == null)
            {
                result = null;
            }
            else
            {
                MethodInfo getMethod = pi.GetGetMethod();
                if (getMethod == null)
                {
                    result = null;
                }
                else
                {
                    result = getMethod.Invoke(obj, Constants.EmptyObjectArray);
                }
            }
            return result;
        }

        public static object CreateInstance(this Type @this)
        {
            object result;
            try
            {
                object obj = Activator.CreateInstance(@this);
                result = obj;
            }
            catch
            {
                result = null;
            }
            return result;
        }

        public static byte[] ToBytes(this string value, Encoding encode)
        {
            return encode.GetBytes(value);
        }

        public static byte[] ToBytes(this string value)
        {
            return value.ToBytes(Encoding.Default);
        }

        public static byte[] ToASCIIBytes(this string value)
        {
            return value.ToBytes(Encoding.ASCII);
        }

        public static string Encode(this string value, Encoding encode)
        {
            Guard.ArgumentNotNull(value, "value");
            Encoding unicode = Encoding.Unicode;
            byte[] bytes = Encoding.Convert(unicode, encode, value.ToBytes(unicode));
            return bytes.GetString(encode);
        }

        public static string Encode(this string value, Encoding sencode, Encoding tencode)
        {
            Guard.ArgumentNotNull(value, "value");
            byte[] bytes = Encoding.Convert(sencode, tencode, value.ToBytes(sencode));
            return bytes.GetString(tencode);
        }

        public static string UrlEncode(this string source, EnumEncodingType encodingType = EnumEncodingType.UTF_8)
        {
            string result;
            if (!string.IsNullOrEmpty(source))
            {
                Encoding encoding = Encoding.GetEncoding(encodingType.GetDescription());
                result = HttpUtility.UrlEncode(source, encoding);
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static string UrlDecode(this string source, EnumEncodingType encodingType = EnumEncodingType.UTF_8)
        {
            string result;
            if (!string.IsNullOrEmpty(source))
            {
                Encoding encoding = Encoding.GetEncoding(encodingType.GetDescription());
                result = HttpUtility.UrlDecode(source, encoding);
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static string HtmlDecode(this string source)
        {
            string result;
            if (!string.IsNullOrEmpty(source))
            {
                result = HttpUtility.HtmlDecode(source);
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }

        public static string HtmlEncode(this string source)
        {
            string result;
            if (!string.IsNullOrEmpty(source))
            {
                result = HttpUtility.HtmlEncode(source);
            }
            else
            {
                result = string.Empty;
            }
            return result;
        }
        /// <summary>
        /// Checks whatever given collection object is null or has no item.
        /// </summary>
        public static bool IsNullOrEmpty<T>(this ICollection<T> source)
        {
            return source == null || !source.Any();
        }

        /// <summary>
        /// Adds an item to the collection if it's not already in the collection.
        /// </summary>
        /// <param name="source">Collection</param>
        /// <param name="item">Item to check and add</param>
        /// <typeparam name="T">Type of the items in the collection</typeparam>
        /// <returns>Returns True if added, returns False if not.</returns>
        public static bool AddIfNotContains<T>(this ICollection<T> source, T item)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            if (source.Contains(item))
            {
                return false;
            }

            source.Add(item);
            return true;
        }
        public static bool IsNullOrEmpty(this string value)
        {
            return string.IsNullOrEmpty(value);
        }

        public static bool IsNullOrEmptyOrWhiteSpace(this string value)
        {
            bool flag = value.IsNullOrEmpty();
            if (!flag)
            {
                flag = value.Trim().IsNullOrEmpty();
            }
            return flag;
        }

        public static bool IsValid(this string value)
        {
            return !value.IsNullOrEmptyOrWhiteSpace();
        }

        public static bool IsInvalid(this string value)
        {
            return value.IsNullOrEmptyOrWhiteSpace();
        }

        public static string ToSafeString(this object obj)
        {
            string result;
            if (obj == null)
            {
                result = string.Empty;
            }
            else
            {
                result = obj.ToString();
            }
            return result;
        }

        public static string ToReverse(this string obj)
        {
            char[] array = obj.ToCharArray();
            Array.Reverse(array);
            return new string(array);
        }

        public static string TrimEnd(this string value, string end, StringComparison comparison = StringComparison.Ordinal)
        {
            string result;
            if (value.IsInvalid())
            {
                result = value;
            }
            else if (end.IsInvalid())
            {
                result = value.TrimEnd(new char[0]);
            }
            else if (!value.EndsWith(end, comparison))
            {
                result = value;
            }
            else
            {
                int length = value.LastIndexOf(end, comparison);
                result = value.Substring(0, length);
            }
            return result;
        }

        public static string TrimStart(this string value, string star)
        {
            string result;
            if (star.IsInvalid())
            {
                result = value.TrimStart(new char[0]);
            }
            else if (!value.StartsWith(star))
            {
                result = value;
            }
            else
            {
                result = value.Substring(star.Length);
            }
            return result;
        }

        public static bool IsMatch(this string source, string pattern, RegexOptions options)
        {
            return !source.IsInvalid() && Regex.IsMatch(source, pattern, options);
        }

        public static bool IsMatch(this string source, string pattern)
        {
            return !source.IsInvalid() && source.IsMatch(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        }

        public static Match Match(this string source, string pattern)
        {
            return source.Match(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        }

        public static Match Match(this string source, string pattern, RegexOptions options)
        {
            return Regex.Match(source, pattern, options);
        }

        public static bool Contains(this string value, string match, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase)
        {
            return value.IndexOf(match, comparison) > -1;
        }

        public static bool IsChinese(this char value)
        {
            return value >= '一' && value <= '龻';
        }

        public static bool IsHasChinese(this string value)
        {
            return value.Any((char c) => c.IsChinese());
        }

        public static string Format(this string @this, object arg0)
        {
            return string.Format(@this, arg0);
        }

        public static string Format(this string @this, object arg0, object arg1)
        {
            return string.Format(@this, arg0, arg1);
        }

        public static string Format(this string @this, object arg0, object arg1, object arg2)
        {
            return string.Format(@this, arg0, arg1, arg2);
        }

        public static string Format(this string @this, params object[] arg0)
        {
            return string.Format(@this, arg0);
        }

        public static decimal ToDecimal(this string value)
        {
            if (decimal.TryParse(value, out decimal result))
            {
                return result;
            }
            throw new InvalidCastException("不能将字符串\"" + value + "\"转换为Decimal数字。");
        }

        public static decimal ToSafeDecimal(this string value)
        {
            decimal result;
            if (decimal.TryParse(value, out decimal num))
            {
                result = num;
            }
            else
            {
                result = 0m;
            }
            return result;
        }

        public static double ToDouble(this string value)
        {
            if (double.TryParse(value, out double result))
            {
                return result;
            }
            throw new InvalidCastException("不能将字符串\"" + value + "\"转换为double数字。");
        }

        public static double ToSafeDouble(this string value)
        {
            double result;
            if (double.TryParse(value, out double num))
            {
                result = num;
            }
            else
            {
                result = 0.0;
            }
            return result;
        }
        public static string GetUnitSign(this Enum @this)
        {
            return _CacheDescriptions.GetOrAdd(@this, delegate (Enum key)
            {
                Type type = key.GetType();
                FieldInfo field = type.GetField(key.ToString());
                return (field == null) ? key.GetUnitSigns(",") : GetUnitSign(field);
            });
        }

        public static string GetUnitSigns(this Enum @this, string separator = ",")
        {
            string[] array = @this.ToString().Split(new char[]
            {
                ','
            });
            string[] array2 = new string[array.Length];
            Type type = @this.GetType();
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo field = type.GetField(array[i].Trim());
                if (!(field == null))
                {
                    array2[i] = GetUnitSign(field);
                }
            }
            return string.Join(separator, array2);
        }
        public static string GetDescription(this Enum @this)
        {
            return _CacheDescriptions.GetOrAdd(@this, delegate (Enum key)
            {
                Type type = key.GetType();
                FieldInfo field = type.GetField(key.ToString());
                return (field == null) ? key.GetDescriptions(",") : GetDescription(field);
            });
        }

        public static string GetDescriptions(this Enum @this, string separator = ",")
        {
            string[] array = @this.ToString().Split(new char[]
            {
                ','
            });
            string[] array2 = new string[array.Length];
            Type type = @this.GetType();
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo field = type.GetField(array[i].Trim());
                if (!(field == null))
                {
                    array2[i] = GetDescription(field);
                }
            }
            return string.Join(separator, array2);
        }

        private static string GetDescription(FieldInfo field)
        {
            Attribute customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false);
            return (customAttribute == null) ? string.Empty : ((DescriptionAttribute)customAttribute).Description;
        }

        private static string GetUnitSign(FieldInfo field)
        {
            Attribute customAttribute = Attribute.GetCustomAttribute(field, typeof(UnitSignAttribute), false);
            return (customAttribute == null) ? string.Empty : ((UnitSignAttribute)customAttribute).UnitSign;
        }

        public static string GetDefaultValue(this Enum @this)
        {
            return TypeExtension._CacheDefaultValues.GetOrAdd(@this, delegate (Enum key)
            {
                Type type = key.GetType();
                FieldInfo field = type.GetField(key.ToString());
                return (field == null) ? key.GetDefaultValues(",") : TypeExtension.GetDefaultValue(field);
            });
        }

        public static string GetDefaultValues(this Enum @this, string separator = ",")
        {
            string[] array = @this.ToString().Split(new char[]
            {
                ','
            });
            string[] array2 = new string[array.Length];
            Type type = @this.GetType();
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo field = type.GetField(array[i].Trim());
                if (!(field == null))
                {
                    array2[i] = TypeExtension.GetDefaultValue(field);
                }
            }
            return string.Join(separator, array2);
        }

        private static string GetDefaultValue(FieldInfo field)
        {
            Attribute customAttribute = Attribute.GetCustomAttribute(field, typeof(DefaultValueAttribute), false);
            return (customAttribute == null) ? string.Empty : ((DefaultValueAttribute)customAttribute).Value.ToString();
        }

        public static bool Has(this Enum value, Enum target)
        {
            Guard.ArgumentNotNull(value, "Enum value");
            Guard.ArgumentNotNull(target, "Enum target");
            return !(value.GetType() != target.GetType()) && (value.GetHashCode() & target.GetHashCode()) == target.GetHashCode();
        }

        public static T Remove<T>(this Enum value, Enum target)
        {
            Guard.ArgumentNotNull(value, "Enum value");
            Guard.ArgumentNotNull(target, "Enum target");
            int value2 = value.GetHashCode() & ~target.GetHashCode();
            return value2.ToEnum<T>();
        }

        public static string GetEnumNameByValue<T>(this object value)
        {
            Type typeFromHandle = typeof(T);
            if (typeFromHandle.IsEnum)
            {
                return Enum.GetName(typeFromHandle, value);
            }
            throw new InvalidCastException("必须是枚举类型才能获取枚举名称。");
        }

        /// <summary>
        /// 获取字段Description
        /// </summary>
        /// <param name="fieldInfo">FieldInfo</param>
        /// <returns>DescriptionAttribute[] </returns>
        public static DescriptionAttribute[] GetDescriptAttribute(this FieldInfo fieldInfo)
        {
            if (fieldInfo != null)
            {
                return (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            }
            return null;
        }

        /// <summary>
        /// 根据Description获取枚举
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="description">枚举描述</param>
        /// <returns>枚举</returns>
        public static T GetEnumName<T>(this string description)
        {
            Type _type = typeof(T);
            foreach (FieldInfo field in _type.GetFields())
            {
                DescriptionAttribute[] _curDesc = field.GetDescriptAttribute();
                if (_curDesc != null && _curDesc.Length > 0)
                {
                    if (_curDesc[0].Description == description)
                        return (T)field.GetValue(null);
                }
                else
                {
                    if (field.Name == description)
                        return (T)field.GetValue(null);
                }
            }
            throw new InvalidCastException(string.Format("{0} 未能找到对应的枚举.", description));
        }

        public static T ToEnumByValue<T>(this object value)
        {
            return value.GetEnumNameByValue<T>().ToEnum<T>();
        }

        public static T ToEnum<T>(this string name)
        {
            Type typeFromHandle = typeof(T);
            if (typeFromHandle.IsEnum)
            {
                return (T)Enum.Parse(typeof(T), name, true);
            }
            throw new InvalidCastException("必须是枚举类型才能转换。");
        }

        public static T ToEnum<T>(this int value)
        {
            return value.ToString().ToEnum<T>();
        }

        public static T ToSafeEnum<T>(this string value, T defaultValue)
        {
            T result;
            try
            {
                result = value.ToEnum<T>();
            }
            catch
            {
                result = defaultValue;
            }
            return result;
        }

        public static T ToEnum<T>(this string[] values)
        {
            Guard.ArgumentNotNull(values, "values");
            Type typeFromHandle = typeof(T);
            if (!typeFromHandle.IsEnum)
            {
                throw new InvalidCastException("必须是枚举类型才能转换。");
            }
            List<string> list = new List<string>();
            foreach (string name in values)
            {
                List<string> list2 = list;
                T t = name.ToEnum<T>();
                list2.Add(t.ToString());
            }
            return string.Join(",", list.ToArray()).ToEnum<T>();
        }

        /// <summary>
        /// 将枚举转换为ArrayList
        /// 说明：
        /// 若不是枚举类型，则返回NULL
        /// 单元测试-->通过
        /// </summary>
        /// <param name="type">枚举类型</param>
        /// <returns>ArrayList</returns>
        public static ArrayList ToArrayList(this Type type)
        {
            if (type.IsEnum)
            {
                ArrayList _array = new ArrayList();
                Array _enumValues = Enum.GetValues(type);
                foreach (Enum value in _enumValues)
                {
                    _array.Add(new KeyValuePair<Enum, string>(value, GetDescription(value)));
                }
                return _array;
            }
            return null;
        }

        public static ArrayList ToDescriptionList(this Type type)
        {
            if (type.IsEnum)
            {
                ArrayList _array = new ArrayList();
                Array _enumValues = Enum.GetValues(type);
                foreach (Enum value in _enumValues)
                {
                    _array.Add(GetDescription(value));
                }
                return _array;
            }
            return null;
        }

        public static ObservableCollection<KeyAndValue> ToKeyAndDescriptionList(this Type type)
        {
            if (type.IsEnum)
            {
                ObservableCollection<KeyAndValue> list = new ObservableCollection<KeyAndValue>();

                Array _enumValues = Enum.GetValues(type);
                foreach (Enum value in _enumValues)
                {
                    list.Add(new KeyAndValue()
                    {
                        Key = Convert.ToInt32(value),
                        Value = GetDescription(value)
                    });
                }
                return list;
            }
            return null;
        }

        public static ObservableCollection<NameAndValue> ToValueAndDescriptionList(this Type type)
        {
            if (type.IsEnum)
            {
                ObservableCollection<NameAndValue> list = new ObservableCollection<NameAndValue>();

                Array _enumValues = Enum.GetValues(type);
                foreach (Enum value in _enumValues)
                {
                    list.Add(new NameAndValue()
                    {
                        Name = value.ToString(),
                        Value = GetDescription(value)
                    });
                }
                return list;
            }
            return null;
        }

        public static ArrayList ToDefalutValueList(this Type type)
        {
            if (type.IsEnum)
            {
                ArrayList _array = new ArrayList();
                Array _enumValues = Enum.GetValues(type);
                foreach (Enum value in _enumValues)
                {
                    _array.Add(new KeyValuePair<Enum, string>(value, GetDefaultValue(value)));
                }
                return _array;
            }
            return null;
        }

        private const int LOW_CHINESE = 19968;

        private const int HEIGHT_CHINESE = 40891;

        private static readonly ConcurrentDictionary<Enum, string> _CacheDescriptions = new ConcurrentDictionary<Enum, string>();
        private static readonly ConcurrentDictionary<Enum, string> _CacheDefaultValues = new ConcurrentDictionary<Enum, string>();
    }
}