他の回答で指摘されているように、その割り当ての有効期間のため、 String.Intern の使用には非常に注意する必要があります。頻繁に使用される文字列の小さなセットの場合、これが適切な場合があります。
このシナリオでは、.Net の XML シリアライザーのパターンに従うことにしました。彼らはクラス呼び出し "System.Xml.NameTable" を使用して、XML ドキュメント内の一意の文字列を解決します。上記の「dbc」で提供された実装パターンに従いましたが、String.Intern の代わりに NameTable を使用しました。
public class JsonNameTable
: System.Xml.NameTable
{
}
public class JsonNameTableConverter
: JsonConverter
{
private JsonNameTable _nameTable;
public JsonNameTableConverter(JsonNameTable nameTable)
{
_nameTable = nameTable;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var s = reader.TokenType == JsonToken.String ? (string)reader.Value : (string)Newtonsoft.Json.Linq.JToken.Load(reader); // Check is in case the value is a non-string literal such as an integer.
if (s != null)
{
s = _nameTable.Add(s);
}
return s;
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
そして、使用法コードで、コンバーターを Json 設定に設定します
JsonNameTable nameTable = new JsonNameTable();
settings.Converters.Add(new JsonNameTableConverter(nameTable));
これにより、文字列を共有し、JsonNameTable への参照を使用して文字列の有効期間を制御できます。
ここで改善できる可能性があります。NameTable は、char[]、開始インデックス、および終了インデックスを指定すると、実際には既存の文字列を返します。ストリームから文字列が読み取られる 1 レベル下の nameTable を取得して、重複文字列の作成を回避することも可能です。ただし、Json.Netでそれを行う方法がわかりませんでした