私はこのようなタイプを持っています:
class Foo<T>
{
public string Text { get; set; }
public T Nested { get; set; }
public static string ToJson(Foo<T> foo) { [...] }
}
ToJson
Foo<Bar>
微調整では実現不可能な方法で、インスタンスを JSON にシリアライズしますJsConfig
。また、ToJson
ServiceStack.Text に依存してシリアライズします。Nested
これは のインスタンスになる可能性がありますFoo<Baz>
。
残念ながら、JsConfig
実装されている方法は、 forおよび other forJsConfig<T>
の静的変数のセットがあることを意味します。また、AFAIK、ServiceStack.Text は、オープン ジェネリック型 (つまり、のようなもの) の JSON シリアル化を構成する方法を提供しません。この静的コンストラクターを作成して、この問題を解決しようとしました:Foo<Bar>
Foo<Baz>
JsConfig.Add(typeof(Foo<>), config)
Foo<T>
static Foo() {
JsConfig<Foo<T>>.RawSerializeFn = ToJson;
}
これは常に機能するわけではありません。これは、静的コンストラクターがランタイムによって呼び出される順序によって異なります。どうやら、 ServiceStack.Text はシリアライザー関数をキャッシュし、API で操作が呼び出される順序に応じて、静的コンストラクターが呼び出される前にそれを実行することがあります。
var outer = new Foo<Baz> { Text = "text" };
outer.ToJson(); // OK, because Nested is null
var inner = new Foo<Bar>();
inner.ToJson(); // OK, because JsConfig<Foo<Bar>>.RawSerializeFn is Foo<T>.ToJson
outer.Nested = inner;
outer.ToJson(); // NOT OK, because SS.Text uses the default serializer for Foo<T>, not Foo<T>.ToJson
JsConfig<Foo<T>>
T は実質的に任意の型 (他のジェネリック型であっても) になる可能性があるため、事前にすべてのシリアライザーを設定することはできません。
ServiceStack.Text でオープン ジェネリック型 (ネストできる) のカスタム シリアル化ルーチンを定義することは可能ですか?