まず、protobuf-netは、の代わりに100%低下することを意図しておらず、そのように主張していませんBinaryFormatter
。機能が少し異なります。
少し振り返ってみませんか?基本的にはのサポートがありImplicitFields
ますが、現在これはを介してのみ利用可能であり[ProtoContract]
、を介して便利に行うことはできませんRuntimeTypeModel
。これは少し面倒で、私のリストにあります。ただし、暗黙フィールドは少し危険であると考えていることを指摘しておく必要があります。これは、DTO内部が変更されないことがわかっている場合にのみ実行する必要があります。しかし:あなたの質問に答えるために、あなたはあなたが期待するタイプを繰り返し、それらを手動でモデルに追加することができます:
static void Main()
{
Prepare(typeof(A), typeof(B), typeof(C));
// if you really want to use IFormatter...
var formatter = RuntimeTypeModel.Default.CreateFormatter(typeof (A));
var obj = new A {Bs = new B[] {new B()}};
using (var ms = new MemoryStream())
{
formatter.Serialize(ms, obj);
ms.Position = 0;
var clone = formatter.Deserialize(ms);
}
}
static void Prepare(params Type[] types)
{
if(types != null) foreach(var type in types) Prepare(type);
}
static void Prepare(Type type)
{
if(type != null && !RuntimeTypeModel.Default.IsDefined(type))
{
Debug.WriteLine("Preparing: " + type.FullName);
// note this has no defined sort, so invent one
var props = type.GetProperties();
Array.Sort(props, (x, y) => string.Compare(
x.Name, y.Name, StringComparison.Ordinal));
var meta = RuntimeTypeModel.Default.Add(type, false);
int fieldNum = 1;
for(int i = 0 ; i < props.Length ; i++)
{
meta.Add(fieldNum++, props[i].Name);
}
}
}
ここでの使用IFormatter
は完全に不要であることに注意してください。RuntimeTypeModel.Default.Serialize(...)
またはを使用することもできますSerializer.Serialize<T>(...)
。
脚注として:モデルをもっと定義することをお勧めします...繰り返します。例えば:
RuntimeTypeModel.Default.Add(typeof(A)).Add("Bs", "Cs");
RuntimeTypeModel.Default.Add(typeof(B)).Add("Foo");
RuntimeTypeModel.Default.Add(typeof(C)).Add("Bar", "Blap", "Blop");