[转]自定义序列化对象

很多时候,我们需要将对象序列化成字符串保存到内存、磁盘或者 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 - 11);
      }

      
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 - 11);
      }

      
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 - 11);
  
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<stringint> dictionary;

  
public Dictionary<stringint> 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<stringint>();
    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);
  }

}

posted @ 2007-07-20 00:06  wenanry  阅读(428)  评论(0编辑  收藏  举报