gpt4 book ai didi

c# - 使用 Json.NET 替代 int、float 和 decimal

转载 作者:太空狗 更新时间:2023-10-29 21:44:20 26 4
gpt4 key购买 nike

我们使用 Json.net 进行序列化。我们希望允许几乎任何类型的用户定义的类/消息是可序列化的。

Json.net 无法开箱即用的一件事是,如果您将 intfloatdecimal 存储在 对象字段。例如

 public class SomeMessage
{
public object Something {get;set;}
}

如果我在 Something 字段中存储 intfloatdecimal,它将被反序列化为 longdouble(因为 json.net 只能猜测 json 中原语的类型(“foo”:123 <- int 或 long?)

我完全知道我可以在属性上使用正确的类型并设置各种提示。

但我想为任何随机类/消息解决这个问题。

我目前的方法是自定义 JsonConverter,它处理上述类型,然后将它们序列化为代理类型,该代理类型将值保存为字符串和这是什么类型的鉴别器。然后在 ReadJson 上,我将其恢复为正确的类型。

这样做有很多过热的地方。特别是对于代理类型的类型名。 “foo.bar.baz.PrimitiveSurrogate, mylib”

我可以自定义此类型名称的存储方式吗?例如如果我想将别名应用于某些特定类型?

还有其他方法吗?我可以将整个东西序列化为一个特殊的字符串,它会更小,但话又说回来,这感觉很不稳定。

那么,如果我想在存储在无类型结构中时保持原语的正确类型,我有什么选择?

[编辑]

普通 Json:

{
"foo":123
}

对比

我们当前的代理版本:

{
"foo": {
"$type":"Akka.Serialization.PrimitiveSurrogate, Akka",
"V":"123",
"T":1
}
}

我可以只用 `"V":"123L"替换 V 和 T 并解析后缀,因为我们只在该类型中存储 int、float 和 decimal,所以我们可以轻松地拥有一个硬编码的描述符。

但是,这仍然没有摆脱代理本身的 $type,我想至少将其缩短为类似 `"$type":"Surrogate"或那个方向的东西。

[再次编辑]我把它归结为:

{"$type":"Akka.Util.PrimitiveSurrogate, Akka","V":"F123.456"}

但我真的很想摆脱长类型名并以某种方式替换为别名。

[再次编辑]

我现在已经把它归结为:

{"$":"M123.456"}

在我看来,这已经足够好了。我们不需要与任何其他 json 系统互操作,它只是我们两端的框架,所以即使它不漂亮,组成的格式也能工作。

最佳答案

有效负载的大小有多重要?例如,您可以嵌入有关每个原语类型的元数据,本质上是将数据契约与数据捆绑在一起。例如:

{
"someInteger": 123,
"$someInteger.clrType": " System.Int32"
}

编辑:

如果负载大小是最重要的,你可以这样做:

{
"someInteger.i": 123
}

这会将有效载荷增加到每个原始值两个字符。我很确定这个点可以安全地用作分隔符;也就是说,CLR 标识符不可能有标识符“someInteger.i”,尽管我会根据规范仔细检查这一点(CLR 中允许的标识符字符由以下文档管理,附件 7 http://www.unicode.org/reports/tr15/tr15-18.html#Programming%20Language%20Identifiers) .

如果您真的想压缩它,您可以删除分隔符 (.) 并使用 CLR 规范不允许的单个 Unicode 字符作为属性名称的后缀,以表示所需的原始类型。有点 hacky,但它会减少另一个字节的有效负载。 ;-)

关于c# - 使用 Json.NET 替代 int、float 和 decimal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29009581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com