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