在C#中,你如何单向序列化的非序列化?
通常情况下,我需要序列化一个对象,用于logging或debugging。 这是一个单向序列化 – 我不需要稍后再取出它,我只需要将一个对象转换成一个string,将它写入某处。
是的,是的 – 这就是为什么你应该总是重写ToString
方法。 我知道这个。 但是我经常处理我没写的东西,也不能改变。 另外,我不想为每个我写的类编写和更新一个ToString方法。
XML序列化提供了一个看似完美的解决scheme – 只是把这个对象压缩成XML。 但有很多限制,特别是你不能序列化IDictionary,你必须有一个无参数的构造函数。 我可以在课堂上解决这些问题,但是 – 我又经常和其他人一起上课。
那么,获得一个对象的综合string表示的解决scheme是什么? 有什么简单的,我失踪?
如何用自己的逻辑扩展方法(也许一些反思)?
public static class SerializerExtension { public static String OneWaySerialize(this Object obj) { if (Object.ReferenceEquals(obj, null)) { return "NULL"; } if (obj.GetType().IsPrimitive || obj.GetType() == typeof(String)) { if (obj is String) return String.Format("\"{0}\"", obj); if (obj is Char) return String.Format("'{0}'", obj); return obj.ToString(); } StringBuilder builder = new StringBuilder(); Type objType = obj.GetType(); if (IsEnumerableType(objType)) { builder.Append("["); IEnumerator enumerator = ((IEnumerable)obj).GetEnumerator(); Boolean moreElements = enumerator.MoveNext(); while (moreElements) { builder.Append(enumerator.Current.OneWaySerialize()); moreElements = enumerator.MoveNext(); if (moreElements) { builder.Append(","); } } builder.Append("]"); } else { builder.AppendFormat("{0} {{ ", IsAnonymousType(objType) ? "new" : objType.Name); PropertyInfo[] properties = objType.GetProperties(); for (Int32 p = properties.Length; p > 0; p--) { PropertyInfo prop = properties[p-1]; String propName = prop.Name; Object propValue = prop.GetValue(obj, null); builder.AppendFormat("{0} = {1}", propName, propValue.OneWaySerialize()); if (p > 1) { builder.Append(", "); } } builder.Append(" }"); } return builder.ToString(); } // http://stackoverflow.com/a/2483054/298053 private static Boolean IsAnonymousType(Type type) { if (type == null) { return false; } return Attribute.IsDefined(type, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false) && type.IsGenericType && type.Name.Contains("AnonymousType") && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$")) && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic; } private static Boolean IsEnumerableType(Type type) { if (type == null) { return false; } foreach (Type intType in type.GetInterfaces()) { if (intType.GetInterface("IEnumerable") != null || (intType.IsGenericType && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>))) { return true; } } return false; } }
像这样调用它:
someDefinedObject.OneWaySerialize();
Revisisons
- 初始版本
- 更新12.26.2012
- 增加了对IEnumerable的检查(感谢aboveyou00)
- 增加了对匿名types的检查(输出时只标注“新”)
如果你对JSON序列化感到满意, Json.NET是解决这个问题的好办法。