Hashtable
がうまくいかない理由は、は、あなたがそれに入れようとしているものがわからないからです。。 protobuf-netは契約ベースのシリアライザです。 Hashtable
は本質的にはobject
-to-object
のマップです。 object
はで、ではありません。実際、契約とは正反対です。対照的に、Dictionary<int, SomeType>
は(SomeType
を契約書として使用できる限り)のようにうまく動作します。
ISite
が機能しないのは、とおそらくのインターフェイスです。インタフェースは実装であり、データではありません。それが起こると、protobuf-net はにインターフェイスメンバーのサポートをいくつか制限していますが、インターフェイスをDTO(データ契約)から遠ざけるほうがよいです。どのようなタイプのISite
実装を作成する必要がありますか?それにはどんなデータが必要ですか?使用したSomeFunSite : ISite
は、どのようにインスタンス化され、物事に結び付けられるのですか?シリアライザが必要とする質問が多すぎます:シリアライザが望んでいることは、「Foo
をシリアル化しています; Foo
には2つの整数、文字列、Bar
がありますが、それについてはSuperBar : Bar
サブクラスもありますある場合"。それは十分な問題以上のものです。
良い契約:
[ProtoContract]
public class MyData {
[ProtoMember(1)]
public Dictionary<int, SomeType> Items {get; } = new Dictionary<int, SomeType>();
[ProtoMember(2)]
public SomethingElse Whatever { get;set;}
}
悪い契約:常にではない:いくつかのケースでは
[ProtoContract]
public class MyData {
[ProtoMember(1)]
public Hashtable Items {get; } = new Hashtable();
[ProtoMember(2)]
public ISometing Whatever { get;set;}
}
それはあなたがやろうとしたが、されているかを理解するためにRuntimeTypeModel
を設定する可能性があります。それは文脈に依存するだろう。私が持っていない文脈。
編集:マイナー明確化:{get;}
のみのプロパティは、今ではなく、現在のNuGetビルドで、ソースコードでサポートされている - 基本的には、まだそれを使用しないでください!
は、ここで保存する同様のデータをマーキングの実行可能な例を示します
using ProtoBuf;
using System;
using System.Collections.Generic;
static class Program
{
static void Main()
{
var obj = new MyData
{
Site = new BasicSite { BaseHost = "http://somesite.org" },
Items =
{
{"key 1", SomeType.Create(123) },
{"key 2", SomeType.Create("abc") },
{"key 3", SomeType.Create(new Whatever { Id = 456, Name = "def" }) },
}
};
var clone = Serializer.DeepClone(obj);
Console.WriteLine($"Site: {clone.Site}");
foreach(var pair in clone.Items)
{
Console.WriteLine($"{pair.Key} = {pair.Value}");
}
}
}
[ProtoContract]
class MyData
{
private readonly Dictionary<string, SomeType> _items
= new Dictionary<string, SomeType>();
[ProtoMember(1)]
public Dictionary<string, SomeType> Items => _items;
[ProtoMember(2)]
public ISite Site { get; set; }
}
[ProtoContract]
[ProtoInclude(1, typeof(SomeType<int>))]
[ProtoInclude(2, typeof(SomeType<string>))]
[ProtoInclude(3, typeof(SomeType<Whatever>))]
abstract class SomeType
{
public object Value { get { return UntypedValue; } set { UntypedValue = value; } }
protected abstract object UntypedValue { get; set; }
public static SomeType<T> Create<T>(T value) => new SomeType<T> { Value = value };
}
[ProtoContract]
class SomeType<T> : SomeType
{
[ProtoMember(1)]
public new T Value { get; set; }
protected override object UntypedValue { get => Value; set => Value = (T)value; }
public override string ToString() => Value?.ToString() ?? "";
}
[ProtoContract]
class Whatever
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
public override string ToString() => $"{Id}, {Name}";
}
[ProtoContract]
[ProtoInclude(1, typeof(BasicSite))]
interface ISite
{
void SomeMethod();
}
[ProtoContract]
class BasicSite : ISite
{
void ISite.SomeMethod() { Console.WriteLine(BaseHost); }
[ProtoMember(1)]
public string BaseHost { get; set; }
public override string ToString() => BaseHost;
}
RuntimeTypeModelは、任意のタイプ、あなたが作るだけでなく、クラスに適用されます。 – Evk
'ISite'とは何ですか?それはインターフェースですか?私はそれがうまくいくとは思わない...インターフェースは実装であり、データではない。あなたはそれが何であるかについてより具体的になりますか? –