鉴于以下情况:
[<DataContract>]
type TweetUser = {
[<field:DataMember(Name="followers_count")>] Followers:int
[<field:DataMember(Name="screen_name")>] Name:string
[<field:DataMember(Name="id_str")>] Id:int
[<field:DataMember(Name="location")>] Location:string}
[<DataContract>]
type Tweet = {
[<field:DataMember(Name="id_str")>] Id:string
[<field:DataMember(Name="text")>] Text:string
[<field:DataMember(Name="retweeted")>] IsRetweeted:bool
[<field:DataMember(Name="created_at")>] DateStr:string
[<field:DataMember(Name="user", IsRequired=false)>] User:TweetUser
[<field:DataMember(Name="sender", IsRequired=false)>] Sender:TweetUser
[<field:DataMember(Name="source")>] Source:string}
使用
DataContractJsonSerializer(typeof<Tweet[]>)
反序列化将导致 User 或 Sender 字段为空(至少这是调试器告诉我的)。如果我尝试编写以下内容:
let name = if tweet.User <> null
then tweet.User.Name
else tweet.Sender.Name
编译器发出错误:“类型‘TweetUser’没有‘null’作为正确值”
在这种情况下如何测试空值?
最佳答案
循环扩展@Tomas 的回答;-]
let name = if not <| obj.ReferenceEquals (tweet.User, null)
then tweet.User.Name
else tweet.Sender.Name
或者
let inline isNull (x:^T when ^T : not struct) = obj.ReferenceEquals (x, null)
Unchecked.defaultof<_>
正在做正确的事情并为您的记录类型生成空值;问题是默认的相等运算符使用通用结构比较,它希望您在使用 F# 类型时始终遵循 F# 的规则。在任何情况下,空检查实际上只保证首先进行引用比较。
关于f# - 在 F# 中测试空引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10746618/