gpt4 book ai didi

f# - 记录等于或 GetHashCode 抛出 NullReferenceException

转载 作者:行者123 更新时间:2023-12-04 14:45:43 25 4
gpt4 key购买 nike

我有一些看起来像这样的记录:

[<DataContract>]
type Rec1 = {
[<DataMember>] mutable field1 : int;
[<DataMember>] mutable field2 : string;
}

[<DataContact>]
type Rec2 = {
[<DataMember>] mutable field3 : Rec1;
[<DataMember>] mutable field4 : int;
}

我用 DataContactJsonSerializer将 JSON 反序列化为该结构。这是一个有效的 JSON 值:
{ "field3": null, "field4": 1 }

这意味着在运行时, field3null/Unchecked.defaultOf<_> .在 Visual Studio 2010 中,此测试工作正常:
(deserialize<Rec2> "{ field3: null, field4: 1 }") = { field3 = Unchecked.defaultOf<_>; field4 = 1 } //true

在 Visual Studio 2013 中,相同的代码会抛出 NullReferenceException :
at Rec2.Equals(Rec2 obj) 

偷看ILSpy中的代码,我看到这是生成的:
if(this != null)
{
return obj != null && this.field3.Equals(obj.field3) && this.field4.Equals(obj.field4);
}
return obj == null;

所以问题是编译器假设 field3永远不会为空,自 DataContractJsonSerializer 起就不是这样了将值设置为 null .我试过应用 AllowNullLiteral归因于 Rec1但不允许 F# 记录应用该属性。我怎么能告诉编译器这些字段可以是 null或者重新构建我的类型以允许它工作?

最佳答案

F# 正在生成类型,假设它只会在 F# 中使用,其中 null不可能。因为 [<AllowNullLiteral>]不允许在该元素上使用我认为没有办法控制代码生成以解决这种可能性。我可以想到 2 种方法来解决这个问题

  • Rec2 上实现自定义相等而不是默认的结构相等。这意味着您必须自己编写相等方法,这很不幸,但它应该允许您考虑 null 的可能性。
  • 更改代码生成struct实例而不是 class .这消除了 null 的可能性在任何 CLR 用例中。尽管
  • 这将要求您从记录定义移动到完整类型

    关于f# - 记录等于或 GetHashCode 抛出 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20708782/

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