我正在(反)序列化网络多人游戏的一些数据结构,并且对于每个要(反)序列化的数据结构,我只想定义一次(反)序列化的顺序以实现可维护性。
我可以使用 C# 的抽象类方法来实现我的目标,但是这样做有几个问题:
性能:我不想招致与使用“ref”参数对内置类型有关的装箱
性能:为每个(反)序列化操作添加额外的抽象方法调用也不理想
额外输入:我必须不必要地初始化我正在反序列化的所有变量,因为 C# 不允许我互换传递“ref”和“out”参数
如何避免重复数据结构(反)序列化的定义,同时避免上述部分或全部问题?
(我玩弄了代表和反射,但这个解决方案最容易找到我):
public struct ControllerSnapshot
{
public Vector2 m_lStick;
static private void Op(ref float lStickX, ref float lStickY, Op<float> op)
{
//define (de)serialization order here once and only once
lStickX = op.Invoke(lStickX);
lStickY = op.Invoke(lStickY);
}
public ControllerSnapshot(uLink.BitStream bitStream)
{
OpRead<float> opRead = new OpRead<float>(bitStream);
float lStickX,lStickY;
lStickX = lStickY = 0.0f;//3.can't use "out"; have to match Op's "ref" params
Op(ref lStickX,ref lStickY,opRead);
m_lStick = new Vector2(lStickX,lStickY);
}
public void Serialize(uLink.BitStream bitStream)
{
OpWrite<float> opWrite = new OpWrite<float>(bitStream);
Op(ref m_lStick.x, ref m_lStick.y, opWrite);
}
};
//in order to make the above work this needs to be defined:
abstract class Op<T>
{
public Op(uLink.BitStream bitStream)
{
m_bitStream = bitStream;
}
abstract public T Invoke(T arg);
protected uLink.BitStream m_bitStream;
}
class OpRead<T>:Op<T>
{
public OpRead(uLink.BitStream bitStream) : base(bitStream) { }
override public T Invoke(T arg)
{
return m_bitStream.Read<T>();
}
}
class OpWrite<T>:Op<T>
{
public OpWrite(uLink.BitStream bitStream) : base(bitStream) { }
override public T Invoke(T arg)
{
m_bitStream.Write<T>(arg);
return arg;
}
}
//by contrast, the "obvious" code duplicates the order of (de)serialization, which I
//want to avoid, especially as (de)serialization becomes increasingly complex:
public ControllerSnapshot(uLink.BitStream bitStream)
{
float lStickX,lStickY;
lStickX = bitStream.Read<float>();
lStickY = bitStream.Read<float>();
m_lStick = new Vector2(lStickX,lStickY);
}
public void Serialize(uLink.BitStream bitStream)
{
bitStream.Write<float>(m_lStick.x);
bitStream.Write<float>(m_lStick.y);
}