バイナリデシリアライザでオプション1(big switch文)を使用しました。あなたのコマンドで次に
interface IBinarySerializable
{
void Serialize(BinaryWriter toStream);
void Deserialize(BinaryReader fromStream);
}
:
abstract class Command : IBinarySerializable
{
}
class SomeCommand : Command
{
public int Arg1 { get; set; }
public void Serialize(BinaryWriter toStream)
{
toStream.Write(Arg1);
}
public void Deserialize(BinaryReader fromStream)
{
Arg1 = fromStream.ReadInt32();
}
}
と汎用シリアル化
が
{
object result;
BinaryReader ...;
foreach (var propertyInfo in ...)
{
Func<BinaryReader, object> deserializer;
if (!supportedTypes.TryGetValue(propertyInfo.PropertyType, out deserializer))
{
throw new NotSupportedException(string.Format(
"Type of property '{0}' isn't supported ({1}).", propertyInfo.Name, propertyInfo.PropertyType));
}
var deserialized = deserializer(reader);
propertyInfo.SetValue(result, deserialized, null);
}
}
private static Dictionary<Type, Func<BinaryReader, object>> supportedTypes = new Dictionary<Type, Func<BinaryReader, object>>
{
{ typeof(int), br => br.ReadInt32() },
// etc
};
別のオプションは、コマンドクラス自体が直列化を行うようにすることです:クリーナー方法は何かのようにすることができ方法:
void Serialize<T>(T obj) where T : IBinarySerializable
{
obj.Serialize(_stream);
}
T Deserialize<T>() where T : new(), IBinarySerializable
{
var result = new T();
result.Deserialize(_stream);
return result;
}
しかし、この方法では、いくつかのコードを複製することになるかもしれません。 (一方で、派生したクラスは、あなたのシナリオで意味をな는ことがあれば、それらの親クラスのバージョンのSerialize/Deserializeを呼び出すことができます。)
本当に良いオプションのカップル、ありがとう。最初のコードに向かって傾いているのは、それが現在のコードとうまく適合しているからです。ご協力いただきありがとうございます。 –