c#序列化(紧密型数据结构)(一)

    c#自带各种方便的序列化功能,例如可以序列化类为json,序列化为XML。

    我对C#了解甚少,最近需要做一个unity3D服务器和c++客户端网络通信的功能,所以实现了一个简略序列化函数,搓作留此纪念。

   实现如下:

   首先实现一个动态缓存区,可以自动增大,具有增加数据和获取数据接口,用于进行序列化时使用

   该类使用泛型实现

    Dynamical.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetWork.NetWork
{
    public class Dynamical<T>
    {
        public Dynamical()
        {
            buff = new List<T>(10);
            cur_len = 0;
            max_len = 10;
        }

        public int GetSize()
        {
            return cur_len;
        }

        public void ReSet()
        { 
           cur_len = 0;
        }

        public void AddData(T[] data, int size)
        {
            for (int i = cur_len; i < cur_len + size; i++)
            {
                if (i < max_len)
                {
                    buff[i] = data[i - cur_len];
                }
                else
                {
                    buff.Add(data[i - cur_len]);
                }
            }
            cur_len += size;
            max_len += buff.Count;
        }

        public void RemoveData(int start, int size)
        {
            if (start < 0  || size < 0 || start +size > cur_len)
            {
                return;
            }

            for (int i = 0; i < cur_len - start - size; i++)
            {
                buff[i + start] = buff[start + size + i];
            }
            cur_len -= size;
        }

        void GetData(ref T[] data, int start, int size)
        {
            if (start < 0 || size <= 0 || start + size > cur_len)
            {
                return;
            }

            T[] tmp = new T[size];
            for (int i = 0; i <  size; i ++)
            {
                tmp[i] = buff[i + start];
            }

            data = tmp;
        }

        List<T> buff;
        int cur_len;
        int max_len;
    }
}

1、首先实现一个基类,有两个虚函数,Serializable()、DeSerializable()需要子类去实现

2、再实现一个通用的SerializableBase()、DeSerializableBase()函数,可以序列化反序列化基本类型

当然可以在这个两个函数中增加其他非基本类型的序列化,反序列化,那么子类就只需要不断递归调用Serializable,

SerializableBase就可以实现序列化。DeSerializable,DeSerializableBase实现反序列化对复杂类型也手到擒来。

Serialization.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetWork.NetWork
{
    public class Serialization
    {
        public virtual void Serializable(ref Dynamical<byte> buff)
        {
            // 子类继承
        }

        public virtual void DeSerializable(ref byte[] buff, ref int offset, int size)
        {
            // 子类继承
        }

        public void SerializableBase(ref Dynamical<byte> buff, object obj)
        {
            if (obj is bool)
            {
                buff.AddData(BitConverter.GetBytes((bool)obj), sizeof(bool));
            }
            else if (obj is int)
            {
                buff.AddData(BitConverter.GetBytes((int)obj), sizeof(int));
            }
            else if (obj is float)
            {
                buff.AddData(BitConverter.GetBytes((double)obj), sizeof(float));
            }
            else if (obj is double)
            {
                buff.AddData(BitConverter.GetBytes((double)obj), sizeof(double));
            }
            else if (obj is char)
            {
                buff.AddData(BitConverter.GetBytes((char)obj), sizeof(char));
            }
        }

        public object DeSerializableBase(Type type, ref byte[] buff, ref int offset, int size)
        {
            dynamic obj = null;
            if (type == typeof(bool))
            {
                offset += sizeof(bool);
                if (offset <= size)
                    obj = BitConverter.ToBoolean(buff, offset);
            }
            else if (type == typeof(int))
            {
                offset += sizeof(int);
                if (offset <= size)
                    obj = BitConverter.ToInt32(buff, offset);
            }
            else if (type == typeof(double))
            {
                offset += sizeof(double);
                if (offset <= size)
                    obj = BitConverter.ToDouble(buff, offset);
            }
            else if (type == typeof(float))
            {
                offset += sizeof(double);
                if (offset <= size)
                    obj = BitConverter.ToDouble(buff, offset);
            }
            else if (type == typeof(char))
            {
                offset += sizeof(char);
                if (offset <= size)
                    obj = BitConverter.ToChar(buff, offset);
            }

            return obj;  
        }
    }
    public class ListNode : Serialization
    {
        public int node_id;

        public override void Serializable(ref Dynamical<byte> buff)
        {
            SerializableBase(ref buff, node_id);
        }

        public override void DeSerializable(ref byte[] buff, ref int offset, int size)
        {
            node_id = (int)DeSerializableBase(node_id.GetType(), ref buff, ref offset, size);
        }
    }

    public class ChildClass : Serialization
    {
        public int id;
        public char c;
        public double d;
        public List<ListNode> list;

        public override void Serializable(ref Dynamical<byte> buff)
        {
            SerializableBase(ref buff, id);
            SerializableBase(ref buff, c);
            SerializableBase(ref buff, d);
            int count = list.Count;
            SerializableBase(ref buff, count);
            for (int i = 0; i < count; i++)
            {
                list[i].Serializable(ref buff);
            }
        }

        public override void DeSerializable(ref byte[] buff, ref int offset, int size)
        {
            id = (int)DeSerializableBase(id.GetType(), ref buff, ref offset, size);
            c = (char)DeSerializableBase(c.GetType(), ref buff, ref offset, size);
            d = (double)DeSerializableBase(d.GetType(), ref buff, ref offset, size);
            int count = 0;
            size = (int)DeSerializableBase(count.GetType(), ref buff, ref offset, size);

            for (int i = 0; i < count; i++)
            {
                ListNode node = new ListNode();
                node.DeSerializable(ref buff, ref offset, size);
            }
        }
    }
}

test.cs

        private void Form1_Load(object sender, EventArgs e)
        {
            ChildClass c = new ChildClass();
            Dynamical<byte> dynamical = new Dynamical<byte>();
            c.Serializable(ref dynamical);
            byte[] buff = null;
            dynamical.GetData(ref buff, 0, dynamical.GetSize());
            ChildClass c1 = new ChildClass();
            int offset = 0;
            c1.DeSerializable(ref buff, ref offset, buff.Count());
        }

二、缺点

        每个子类都要实现DeSerializable,Serializable 函数,容易出错,编码也不方便。比起原生的json,xml序列化。不过传输过程中占用的消耗小,适用于网路传输。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值