English 中文(简体)
F# 无效引用测试
原标题:Testing for null reference in F#
  • 时间:2012-05-24 23:19:46
  •  标签:
  • f#

鉴于以下情况:

[<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}

使用 DatacontractJsonSregier( 类型 < Tweet[] & gt;) 进行降序时, 将会导致用户字段或发件人字段无效( 至少调试器告诉我的是这种情况 ) 。

如果我试着写下以下内容:

    let name = if tweet.User <> null 
                  then tweet.User.Name
                  else tweet.Sender.Name

编译器发出错误:“TweetUser 类型没有无效的正确值”

本案中我如何检验无效价值?

最佳回答

循环扩展于 @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<_> is doing the right thing and producing nulls f或 your rec或d types; the issue is that the default equality operat或 uses generic structural comparison, which expects you to always play by F# s rules when using F# types. In any case, a null-check really only warrants referential comparison in the first place.

问题回答

为了给@ildjarn 的评论添加一些细节, 您正在收到错误消息, 因为 F# 不允许使用 < code> null 作为F# 中声明的类型的值。 这样做的动机是 F# 试图从纯 F# 程序中删除 < code> null 的值( 和 < code> NullReferenceException )。

然而,如果您重新使用F# 中未定义的类型, 您仍然可以使用 < code> null (例如, 当调用一个函数, 以 < code> System. random 作为参数时, 您可以给它 < code > null ) 。 这是互操作性需要的, 因为您可能需要将 < code > null 传递到. NET 库, 或者因此接受它 。

在您的示例中, TweetUser 是F# 中宣布的一种( 记录) 类型, 因此语言不允许将 < code> null 视为类型 < code> TweetUser 的值。 但是, 您仍然可以通过 e. description 或 C# 代码获得 < code> null 值。 因此 F# 提供一种“ 不安全” 功能, 产生任何类型的 < code> null 值 - 包括 F# 记录, 这些记录通常不应有 < code> null 值。 这是 uncecked. defaulp<\\\\\ gt; 函数, 您可以用它来实施这样的帮助者 :

let inline isNull x = x = Unchecked.defaultof<_>

或者,如果你用 AllowNullLiteral 属性标记某类型,那么你又对 F# 编译器说,它应该允许 null 作为该特定类型的值,即使它是F# 中声明的类型(通常不允许 null )。

尽管这个问题已经过去,但我并没有看到任何拳击的例子来解决这个问题。 在我的主讲人不允许一字不提但可以从一个角度设定的情况下,我宁可使用拳击。

isNull <| box obj

let isMyObjNull = isNull <| box obj

match box obj with
| null -> (* obj is null *)
| _ -> (* obj is not null *)




相关问题
F#: Storing and mapping a list of functions

I have a number of events that happen in a game. I want to control the time and order at which these events occur. For example: Event 1: Show some text on screen for N frames & play a sound ...

Creating Silverlight 3 applications with F#

Is there an easy way to create Silverlight 3 applications with F# (October CTP)? I have seen the F# for Silverlight, but that only works with the May CTP. I am using Visual Studio Integrated Shell ...

How To Change List of Chars To String?

In F# I want to transform a list of chars into a string. Consider the following code: let lChars = [ a ; b ; c ] If I simply do lChars.ToString, I get "[ a ; b ; c ]". I m trying to get "abc". I ...

Unzipping ZLIB compressed portions of a binary file

I m reading a file(a flash swf) from .Net 3.5 that has a header which states whether the body of the file/Stream is compressed or not. However, I m having problems-after I rewrap the basic File ...

Pretty print a tree

Let s say I have a binary tree data structure defined as follows type a tree = | Node of a tree * a * a tree | Nil I have an instance of a tree as follows: let x = Node (Node (...

F# String Pattern-Matching with Wildcards

As part of a project I have assigned myself as a way of improving my knowledge of F# and functional programming in general, I am attempting to write a string pattern-matching algorithm from scratch ...

热门标签