很多时候,我们需要将对象序列化成字符串保存到内存、磁盘或者 Page.ViewState 中。基于种种原因,我们希望序列化结果尽可能小,尽可能简单,即便用其他的方法(比如正则表达式)也能解析出数据。BinaryFormatter 的结果转换成字符串(或者Base64)长度太大,而 XmlSerializer 对数据类型支持有限,显然内置的序列化引擎不足以满足我们的需求,还是自己丰衣足食。

下面的代码可能还不完善,仅供参考,内容比较简单,不做详述。

/**//// <summary>
/// 序列化
/// </summary>
public static string SerializeObject(object o)
{
  char sep1 = '|';
  char sep2 = ',';
  char sep3 = '=';

  StringBuilder sb = new StringBuilder();

  FieldInfo[] fields = o.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | 
    BindingFlags.NonPublic);

  foreach (FieldInfo field in fields)
  {
    object value = field.GetValue(o);

    if (value != null)
    {
      if (field.FieldType.GetInterface("IDictionary") != null)
      {
        foreach (object key in (value as IDictionary).Keys)
        {
          sb.AppendFormat("{0}{3}{1}{2}", key, (value as IDictionary)[key], sep2, sep3);
        }

        if (sb[sb.Length - 1] == sep2) sb.Remove(sb.Length - 1, 1);
      }
      else if (field.FieldType.GetInterface("IList") != null)
      {
        foreach (object v in (value as IList))
        {
          sb.AppendFormat("{0}{1}", v, sep2);
        }

        if (sb[sb.Length - 1] == sep2) sb.Remove(sb.Length - 1, 1);
      }
      else if (field.FieldType == typeof(Boolean))
      {
        sb.Append((bool)value ? "T" : "");
      }
      else
      {
        sb.Append(value);
      }
    }

    sb.Append(sep1);
  }

  if (sb[sb.Length - 1] == sep1) sb.Remove(sb.Length - 1, 1);
  return sb.ToString();
}

/**//// <summary>
/// 反序列化
/// </summary>
public static T DeserializeObject<T>(string s)
  where T : new()
{
  char sep1 = '|';
  char sep2 = ',';
  char sep3 = '=';

  T o = new T();

  FieldInfo[] fields = o.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | 
    BindingFlags.NonPublic);

  string[] values = s.Split(sep1);

  for (int i = 0; i < fields.Length; i++)
  {
    FieldInfo field = fields[i];
    if (String.IsNullOrEmpty(values[i])) continue;

    if (field.FieldType.GetInterface("IDictionary") != null)
    {
      string[] vs = values[i].Split(sep2);

      IDictionary dictionary = field.GetValue(o) as IDictionary;

      Type key = field.FieldType.IsGenericType ? 
        field.FieldType.GetGenericArguments()[0] : typeof(Object);
      Type value = field.FieldType.IsGenericType ? 
        field.FieldType.GetGenericArguments()[1] : typeof(Object);

      if (dictionary == null)
      {
        dictionary = (IDictionary)Activator.CreateInstance(field.FieldType);
        field.SetValue(o, dictionary);
      }

      foreach (string v in vs)
      {
        string[] ns = v.Split(sep3);
        dictionary.Add(Convert.ChangeType(ns[0], key), Convert.ChangeType(ns[1], value));
      }
    }
    else if (field.FieldType.GetInterface("IList") != null)
    {
      string[] vs = values[i].Split(sep2);

      if (field.FieldType.IsArray)
      {
        Type t = field.FieldType.GetElementType();
        Array array = Array.CreateInstance(t, vs.Length);

        for (int x = 0; x < vs.Length; x++)
        {
          array.SetValue(Convert.ChangeType(vs[x], t), x);
        }

        field.SetValue(o, array);
      }
      else
      {
        IList list = field.GetValue(o) as IList;

        Type t = field.FieldType.IsGenericType ? 
          field.FieldType.GetGenericArguments()[0] : typeof(Object);

        if (list == null)
        {
          list = (IList)Activator.CreateInstance(field.FieldType);
          field.SetValue(o, list);
        }

        foreach (string v in vs)
        {
          list.Add(Convert.ChangeType(v, t));
        }
      }
    }
    else if (field.FieldType == typeof(Boolean))
    {
      field.SetValue(o, values[i] == "T" ? true : false);
    }
    else if (field.FieldType.IsEnum)
    {
      field.SetValue(o, Enum.Parse(field.FieldType, values[i], true));
    }
    else
    {
      field.SetValue(o, Convert.ChangeType(values[i], field.FieldType));
    }
  }

  return o;
}

测试代码

[Serializable]
public class MyClass
{
  private int valueType;

  public int ValueType
  {
    get { return valueType; }
    set { valueType = value; }
  }

  private object obj;

  public object Object
  {
    get { return obj; }
    set { obj = value; }
  }

  private bool boolean;

  public bool Boolean
  {
    get { return boolean; }
    set { boolean = value; }
  }

  private string[] array;

  public string[] Array
  {
    get { return array; }
    set { array = value; }
  }

  private List<string> list;

  public List<string> List
  {
    get { return list; }
    set { list = value; }
  }

  private ArrayList arrayList;

  public ArrayList ArrayList
  {
    get { return arrayList; }
    set { arrayList = value; }
  }

  private Hashtable hashtable;

  public Hashtable Hashtable
  {
    get { return hashtable; }
    set { hashtable = value; }
  }

  private Dictionary<string, int> dictionary;

  public Dictionary<string, int> Dictionary
  {
    get { return dictionary; }
    set { dictionary = value; }
  }
}

class Program
{
  static void Main(string[] args)
  {
    //Test();

    MyClass o = new MyClass();
    o.List = new List<string>();
    o.Dictionary = new Dictionary<string, int>();
    o.ArrayList = new ArrayList();
    o.Hashtable = new Hashtable();

    o.ValueType = 123456;
    o.Object = DateTime.Now;
    o.Boolean = true;

    o.Dictionary.Add("dict1", 1);
    o.Dictionary.Add("dict2", 2);
    
    o.Array = new string[] { "array1", "array2", "array3" };
    
    o.List.Add("list1");
    o.List.Add("list2");
    
    o.ArrayList.Add("ArrayList1");
    o.ArrayList.Add("ArrayList2");
    
    o.Hashtable.Add("Hashtable1", 1);
    o.Hashtable.Add("Hashtable2", 2);

    // SerializeObject

    string s = SerializeObject(o);
    Console.WriteLine(s);

    MyClass m = DeserializeObject<MyClass>(s);
    Console.WriteLine(SerializeObject(m));

    // BinaryFormatter

    BinaryFormatter binary = new BinaryFormatter();
    MemoryStream stream = new MemoryStream();
    binary.Serialize(stream, o);
    s = Convert.ToBase64String(stream.ToArray());
    Console.WriteLine(s);
  }
}

[转]自定义序列化对象相关推荐

  1. FastJson自定义复杂对象序列化

    总结: SerializeFilter是通过编程扩展的方式定制序列化.fastjson支持6种SerializeFilter,用于不同场景的定制序列化. PropertyPreFilter 根据Pro ...

  2. C#自定义序列化反序列化与 ISerializable 接口

    ISerializable 接口 MSDN注解:允许对象控制其自己的序列化和反序列化过程. ISerializable 接口的定义: public interface ISerializable {v ...

  3. python学习-序列化对象(pickle)

    文章目录 序列化(pickle) 序列化(pickle) 序列化对象,引入内置模块: import pickle 序列化写文件使用二进制的方式去写,需要使用wb 我在定义时,类成员变量使用了__修饰, ...

  4. java自定义外部接口_如何使用可外部化的接口在Java中自定义序列化

    java自定义外部接口 在上一篇文章"用示例介绍的有关Java序列化的一切"中 ,我解释了如何使用以下方法序列化/反序列化一个对象 Serializable接口,还说明了如何使用w ...

  5. spring序列化_使用@JsonIdentityInfo的Spring自定义序列化器

    spring序列化 介绍 Spring中从JSON到JSON的序列化/反序列化已广泛用于基于Spring的现代应用程序中. 它基于杰克逊. Jackson可以轻松地将任何POJO序列化为JSON,反之 ...

  6. 如何使用可外部化的接口在Java中自定义序列化

    在上一篇文章"用示例介绍的有关Java序列化的一切"中 ,我解释了如何使用以下方法序列化/反序列化一个对象 Serializable接口,还说明了如何使用writeObject和r ...

  7. 使用@JsonIdentityInfo的Spring自定义序列化器

    介绍 Spring中从JSON到JSON的序列化/反序列化已广泛用于基于Spring的现代应用程序中. 它基于杰克逊. Jackson可以轻松地将任何POJO序列化为JSON,反之亦然. 这段代码写得 ...

  8. kafka自定义序列化器

    <kafka权威指南> Customer.java public class Customer {private int customId;private String customerN ...

  9. Python: 自定义类对象序列化为Json串

    之前已经实现了Python: Json串反序列化为自定义类对象,这次来实现了Json的序列化. 测试代码和结果如下: import Json.JsonToolclass Score:math = 0c ...

最新文章

  1. 控制器框架Struts与策略模式那点事
  2. Smack类库最好的学习资料
  3. ZOJ 3781 Paint the Grid Reloaded
  4. Tomcat集群快速入门:Nginx+Tomcat搭建集群
  5. 动态规划在求解背包问题中的应用(JAVA)--回溯法、记忆化法
  6. 设计实现优雅修改redux数据流的一个库 - redux-chef
  7. Redis-数据结构04-整数集合(intset)
  8. 为什么300的并发能把支持最大连接数4000数据库压死
  9. 小程序的视频代码示例
  10. NISP和CISP考试通过率怎样?
  11. The Code is successfully generatd...使用stm32cude生成工程时报错
  12. 计算机系统与外部交换信息主要通过显示器,微机系统与外部交换信息主要通过什么设备...
  13. 学习做产品阶段性总结
  14. 第一次学游泳技巧_第一次学习游泳
  15. `Caché/IRIS` 代码优化效率提升十一条 - 持续更新
  16. 神经网络原理的简单介绍,神经网络几何原理图
  17. 【商业挖掘】关联规则——Apriori算法(最全~)
  18. 大家都在学JAVA,那么学JAVA到底可以做什么?
  19. [转载]现在你可以定义自己的语言!
  20. 如何去选取第一批要阅读的论文?_【手把手教你写论文】第二期:文献阅读进行时...

热门文章

  1. 浅谈同城双中心的网络部署模型
  2. 从微软的DBML文件中我们能学到什么(它告诉了我们什么是微软的重中之重)~四 分部方法从另一方面定义了类型的操作规范...
  3. SAP面向iOS设备推Cloud Platform SDK工具
  4. STM32F407的硬件I2C
  5. 每日一linux命令
  6. Java数组与容器类分析资料--数组、List和Set、Map等
  7. 准备辞职了,走之前想解决的问题ptr 为空
  8. hadoop的web ui的8088端口打不开一例
  9. $lookup做关联表查询
  10. tensorflow中的log中数字的含义