using ServiceCenter.Extensions; using System.Text; namespace ServiceCenter.Helpers { public class TypeConversionHelper { #region 序列化写入,反序列化 public static Func Serialize; public static Func Deserialize; public static Func DeserializeRaw; public static object SerializeRedisValue(object value) { switch (value) { case null: return null; case string _: case byte[] _: return value; case bool b: return b ? "1" : "0"; case char c: return value; case decimal _: case double _: case float _: case int _: case long _: case sbyte _: case short _: case uint _: case ulong _: case ushort _: return value.ToInvariantCultureToString(); case DateTime time: return time.ToString("yyyy-MM-ddTHH:mm:sszzzz", System.Globalization.DateTimeFormatInfo.InvariantInfo); case DateTimeOffset _: return value.ToString(); case TimeSpan span: return span.Ticks; case Guid _: return value.ToString(); default: if (Serialize != null) return Serialize(value); return value.ConvertTo(); } } public static T DeserializeRedisValue(byte[] valueRaw, Encoding encoding) { if (valueRaw == null) return default(T); var type = typeof(T); var typename = type.ToString().TrimEnd(']'); if (typename == "System.Byte[") return (T)Convert.ChangeType(valueRaw, type); if (typename == "System.String") return (T)Convert.ChangeType(encoding.GetString(valueRaw), type); if (typename == "System.Boolean[") return (T)Convert.ChangeType(valueRaw.Select(a => a == 49).ToArray(), type); if (valueRaw.Length == 0) return default(T); string valueStr = null; if (type.IsValueType) { valueStr = encoding.GetString(valueRaw); bool isNullable = typename.StartsWith("System.Nullable`1["); var basename = isNullable ? typename.Substring(18) : typename; bool isElse = false; object obj = null; switch (basename) { case "System.Boolean": if (valueStr == "1") obj = true; else if (valueStr == "0") obj = false; break; case "System.Byte": if (byte.TryParse(valueStr, out var trybyte)) obj = trybyte; break; case "System.Char": if (valueStr.Length > 0) obj = valueStr[0]; break; case "System.Decimal": if (Decimal.TryParse(valueStr, out var trydec)) obj = trydec; break; case "System.Double": if (Double.TryParse(valueStr, out var trydb)) obj = trydb; break; case "System.Single": if (Single.TryParse(valueStr, out var trysg)) obj = trysg; break; case "System.Int32": if (Int32.TryParse(valueStr, out var tryint32)) obj = tryint32; break; case "System.Int64": if (Int64.TryParse(valueStr, out var tryint64)) obj = tryint64; break; case "System.SByte": if (SByte.TryParse(valueStr, out var trysb)) obj = trysb; break; case "System.Int16": if (Int16.TryParse(valueStr, out var tryint16)) obj = tryint16; break; case "System.UInt32": if (UInt32.TryParse(valueStr, out var tryuint32)) obj = tryuint32; break; case "System.UInt64": if (UInt64.TryParse(valueStr, out var tryuint64)) obj = tryuint64; break; case "System.UInt16": if (UInt16.TryParse(valueStr, out var tryuint16)) obj = tryuint16; break; case "System.DateTime": if (DateTime.TryParse(valueStr, out var trydt)) obj = trydt; break; case "System.DateTimeOffset": if (DateTimeOffset.TryParse(valueStr, out var trydtos)) obj = trydtos; break; case "System.TimeSpan": if (Int64.TryParse(valueStr, out tryint64)) obj = new TimeSpan(tryint64); break; case "System.Guid": if (Guid.TryParse(valueStr, out var tryguid)) obj = tryguid; break; default: isElse = true; break; } if (isElse == false) { if (obj == null) return default(T); return (T)obj; } } if (DeserializeRaw != null) return (T)DeserializeRaw(valueRaw, typeof(T)); if (valueStr == null) valueStr = encoding.GetString(valueRaw); if (Deserialize != null) return (T)Deserialize(valueStr, typeof(T)); return valueStr.ConvertTo(); } #endregion 序列化写入,反序列化 } }