设置 Newtonsoft.Json.JsonConvert 的比较器以用于 HashSet/Dictionary

2024-02-23

我有一个HashSet<string> that JsonConvert.SerializeObject序列化为数组。

当我使用反序列化时JsonConvert.DeserializeObject<HashSet<string>>我得到一个新的HashSet<string>具有相同的值。但是,那Comparer已重置。

// JSON settings
var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

// Create a case insensitive hashset
var h = new HashSet<string>(new string[] {"A", "b"}, StringComparer.OrdinalIgnoreCase);
h.Contains("a"); // TRUE

// Serialise and deserialise with Newtonsoft.Json
string s = JsonConvert.SerializeObject(h, settings);
// s = ["A", "b"]
var newH = JsonConvert.DeserializeObject<HashSet<string>>(s, settings);

// Result is now case-sensitive
newH.Contains("a"); // FALSE
newH.Contains("A"); // TRUE

这是因为JsonConvert uses EqualityComparer<string>.Default,区分大小写。

我如何告诉它使用StringComparer.OrdinalIgnoreCase反而?

我不想包括HashSet<string>.Comparer序列化数据中的属性(我认为它应该是 JSON 中的简单数组),我想在反序列化时指定它。


你可以使用JsonConvert.PopulateObject() http://www.newtonsoft.com/json/help/html/PopulateObject.htm相反,当哈希集是根对象时:

var newH = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
JsonConvert.PopulateObject(s, newH);

当哈希集为not根对象,如果预先分配,Json.NET 将填充它,除非ObjectCreationHandling.Replace http://www.newtonsoft.com/json/help/html/DeserializeObjectCreationHandling.htm已启用。这允许包含类型使用所需的比较器预先分配哈希集,例如:

public class RootObject
{
    public RootObject() { this.Collection = new HashSet<string>(StringComparer.OrdinalIgnoreCase); }

    public HashSet<string> Collection { get; private set; }
}

或者,您可以子类化CustomCreationConverter<HashSet<T>> http://www.newtonsoft.com/json/help/html/DeserializeCustomCreationConverter.htm并使用转换器内所需的比较器分配哈希集Create() http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Converters_CustomCreationConverter_1_Create.htm method:

public class HashSetCreationConverter<T> : CustomCreationConverter<HashSet<T>>
{
    public IEqualityComparer<T> Comparer { get; private set; }

    public HashSetCreationConverter(IEqualityComparer<T> comparer)
    {
        this.Comparer = comparer;
    }

    public override HashSet<T> Create(Type objectType)
    {
        return new HashSet<T>(Comparer);
    }
}

然后执行以下操作:

var newH = JsonConvert.DeserializeObject<HashSet<string>>(s, new HashSetCreationConverter<string>(StringComparer.OrdinalIgnoreCase));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设置 Newtonsoft.Json.JsonConvert 的比较器以用于 HashSet/Dictionary 的相关文章

随机推荐

  • 在 pydantic 日期时间字段中指定时区 [Python]

    我有一个模型 其中定义了日期时间类型字段 如下所示 class DamBaseModel BaseModel class Config allow population by field name True use enum values
  • Spring REST 中的 SSE 实现

    有人可以提供使用 Spring Rest 的 SSE 服务器发送事件 示例吗 基本上我有一个请求 它的响应将由服务器以多个块的形式发送 我希望在 Spring REST Api 中实现服务器和客户端 而不需要像 jersey 这样的第三方
  • 在我的 iOS 应用程序中添加 PayPal pod 后收到 UIWebview api 弃用消息

    我正在构建一个 iOS 应用程序 并在特定的构建版本上添加了 PayPal pod 然后 当我提交该应用程序进行试飞时 我得到了UIWebview API 弃用消息 ITMS 90809 我正在使用 pod PayPal iOS SDK 进
  • 使用 servlet 获取上下文路径

    jboss web xml 中的上下文路径被提到为 Test 但我的战争文件名是Test 0 0 1 我需要使用这个战争文件名HttpServlet 请告诉我函数名称 我试过getContextPath 但它返回测试 谢谢 以下是可用功能的
  • TypeScript:EventEmitter 子类事件的专用签名

    我有一个基类EventEmitter 其中有on将处理程序绑定到特定事件的方法 class EventEmitter on event string handler Function add handler internally prote
  • 如何在 Chrome 开发工具中显示来自特定域的流量

    我只是想知道是否可以仅在 Chrome 开发工具的 网络 选项卡中显示来自特定域的流量 是的 您可以通过输入domain localhost在过滤框中进行过滤localhost域 例如 Notes 过滤器框具有自动完成功能可以帮助您 这就是
  • 如何将TFLite模型转换为量化TFLite模型?

    我有一个 tflite 文件 我想对其进行量化 如何将TFLite模型转换为量化TFLite模型 请注意 您需要源模型来对其进行量化 由于 tflite 模型格式的限制 无法对其进行量化 您的源模型可以是 TF saving model K
  • 跨版本后缀冲突(sbt、Scala-STM、Play-JSON)

    我使用的 JSON 扩展依赖于 Mandubian 的 play json 2 2 SNAPSHOT 一切都很顺利 直到现在我有了一个基于 Scala STM 的项目 sbt 报告以下问题 error Modules were resolv
  • 在移动设备或桌面导航栏时显示汉堡菜单

    我正在进行移动优先设计 并使用 CSS 和 jQuery 制作了一个我非常喜欢的下拉汉堡菜单 但我想做的是 当页面显示在桌面上时 使该汉堡菜单消失 并替换为常规的水平菜单导航栏 我能够使菜单响应 所以至少有一个水平导航栏可以在桌面上下拉 而
  • css 两行1列框布局

    我一直在使用 Flexbox 进行两行一列布局 我使用 Flexbox 是因为我认为 css2 1 无法填充 box B 的剩余空间 在我的 jsFiddle 示例中 我无法让 box C 在右侧向上移动 也无法让 box B 垂直弯曲并填
  • 无需用户凭据的身份验证

    我正在组建一个个人 React 站点 并希望将请求发送到 AWS API 网关 然而 我只想my site能够提取数据 不会有用户模型 并且我曾经使用过的每个身份验证模型都要求用户通过登录执行某些操作 无论是用户 密码还是 AD 有人可以指
  • android-NestDK 卡住了 pincode

    我正在尝试弄清楚如何将我的 NestDK 应用程序连接到 Nest API 使用我的用户名和密码登录后 我收到 使用此 Pincode 连接 Nest XXXXXX 我该怎么办 我预计 access token 请求会在后台发生 但我卡在了
  • Windows Phone:如何禁用 ScrollViewer(列表框)中的触摸滚动?

    我有一个滚动查看器 里面有一个列表框 我需要通过触摸禁用垂直滚动 我该怎么办 换句话说 用户无法通过触摸滚动 我已经放置了按钮 但这是另一个故事
  • Flutter:自定义单选按钮

    How can I create a custom radio button group like this in flutter 这是完整的代码 class CustomRadio extends StatefulWidget overr
  • JDO 异常:“查询需要 1 个参数,但已提供 2 个值。”

    尽管我的 JDO 查询包含TWO declareParameters语句 下面的代码产生一个错误 声称只接受一个参数 查询需要 1 个参数 但已提供 2 个值 这两个参数是amountP and taxP javax jdo Query q
  • 为什么我会收到此 SQL/DB 错误?

    我正在尝试使用 DB2 运行一个简单的 SQL 语句 但遇到了一些问题 我希望在 txt db2 文件中有一个脚本 并让引擎处理所有命令 这是脚本 CONNECT TO MYDB CREATE TABLE PERSONS PID SMALL
  • 垫选择内的模板出口不起作用

    我试图在带有 template outlet 的 mat select 中传递 tmp 但无法显示选择选项 下面是我的代码和 stackblitz 的链接
  • 无法在 IE 中通过 AJAX 更改会话变量

    当我尝试使用 AJAX 更改服务器上的会话变量时 IE 出现一些奇怪的行为 它在 FF Chrome Safari 和我测试过的所有其他浏览器中运行良好 但在 IE 中运行不佳 我在会话变量中为匿名用户维护一个变量 整数 列表 这样我就可以
  • 我可以将 Android 项目中的资源标记为已弃用吗?

    我有一个 android 库 我想将其某些资源标记为已弃用 可绘制对象 尺寸 持续时间 我在某处读到可以将 deprecated deprecated 添加到资源定义中 但它似乎没有做任何事情 在 Android R 中 您可以看到诸如 j
  • 设置 Newtonsoft.Json.JsonConvert 的比较器以用于 HashSet/Dictionary

    我有一个HashSet