protobuf-net は構造化データを保存します。object
は本質的に構造化されておらず、単純に のサブクラスを宣言することも、シリアライゼーションに非常に特殊なルールを持つobject
などの基本的な型を操作することもできません。string
これは私のテストでうまくいきました
もしそうなら、それはバグです。それがうまくいく方法はありません。まったく。これは確かにサポートされているシナリオではなく、正しいことを保証するものではありません (物事が大幅に壊れる可能性もあります)。この場合、明示的に例外を発生させるようにコードを変更します。できるだけ早く修正するために、次を追加しています。
うーん....これは無効なシナリオでしたが、私の回帰テストでは、これには「先行技術」がいくつかあることが強調されています。
(これが、重要なprotobuf-netの質問に答えるたびに、回帰テストとして追加するため、嘘をついていませんでした)
私はそれを除外すべきではないと思いますが、子猫のことを考えてください。それは私の推奨する方法ではありません. 今は殺せないと思うけど。ただし、強調:サブタイプとして (etc)を追加するためにこれを有効にすることはできません。string
カスタムclass
/を意味する API メッセージタイプのみを考慮してくださいstruct
。
この方法では、オブジェクト クラス自体の逆シリアル化が switch ステートメントのように機能するため、シリアル化されたメッセージに型情報を埋め込む必要はありません。
通常、protobuf-net も型情報を埋め込みません;p 型情報を含む「動的」サポートがいくつかありますが、このシナリオでは必要ありません。
型情報を埋め込まずにこれを行うためにサポートされている方法は、次のように、必要な値をカプセル化することです。
[TestFixture]
public class SO11641262
{
[Test]
public void Execute()
{
var model = TypeModel.Create();
model.Add(typeof (FooData), true)
.AddSubType(1, typeof (FooData<string>))
.AddSubType(2, typeof (FooData<int>))
.AddSubType(3, typeof (FooData<SomeOtherType>));
var val = FooData.Create("abc");
var clone = (FooData)model.DeepClone(val);
Assert.AreEqual("abc", clone.ValueUntyped);
Assert.AreEqual(typeof(string), clone.ItemType);
}
[ProtoContract]
public abstract class FooData
{
public static FooData<T> Create<T>(T value)
{
return new FooData<T> {Value = value};
}
public abstract Type ItemType { get; }
public abstract object ValueUntyped { get; set; }
}
[ProtoContract]
public class FooData<T> : FooData
{
[ProtoMember(1)]
public T Value { get; set; }
public override Type ItemType
{
get { return typeof (T); }
}
public override object ValueUntyped
{
get { return Value; }
set { Value = (T) value; }
}
}
[ProtoContract]
public class SomeOtherType {}
}