【发布时间】:2013-07-07 20:13:55
【问题描述】:
有一个类型提供程序,分别具有“string”、“string option”和“int option”类型的三个属性“a”、“b”和“c”。
当我在这些属性中有一个带有“”、None 和 Some 1 的实例时,这会失败:
(row1.a, row1.b, row1.c) |> should equal ("", None, Some 1)
但所有这些都可以正常工作:
row1.a |> should equal ""
row1.b |> should equal None
row1.c |> should equal (Some 1)
("", None, Some 1) |> should equal ("", None, Some 1)
这怎么可能?什么可以使 b 中的 None 与任何其他 None 不同?编译后None只是一个null,.Net中两个null值可以不一样吗?
元组与大多数 F# 类型一样具有结构相等性,因此它应该可以工作。 我收到带有消息的 NUnit.Framework.AssertionException:
Expected: <(, , Some(1))>
But was: <(, , Some(1))>
NUnit 只是调用 .Equals,所以这就是问题所在。
这也失败了:
(row1.a, row1.b, row1.c).Equals(("", None, Some 1)) |> should equal true
row1 的运行时类型是System.Tuple<string,Microsoft.FSharp.Core.FSharpOption<string>,Microsoft.FSharp.Core.FSharpOption<int>>,所以即使这样在理论上也应该可以工作:
row1 |> should equal ("", None, Some 1)
事实上,当元组中没有 None 时它确实如此。
除了类型提供程序之外,我无法使用其他任何东西重现此行为。
【问题讨论】:
-
嗯。您是否将
string*string option*int option与string*obj option*int option进行比较? -
如果我这样做:
let t = ("", None, Some 1) in (row1.a, row1.b, row1.c) |> should equal t工具提示说t是string*'a option*int option,所以它应该可以工作 -
好的,我一直认为问题出在左侧而不是右侧,但在您发表评论后,我意识到这两个:
(row1.a, row1.b, row1.c) |> should equal ("", Option<string>.None, Some 1)和这个:row1 |> should equal ("", Option<string>.None, Some 1)都有效。谢谢 -
有趣...你可以试试
Option<string>.None而不是None吗? -
是的,刚刚做了,这行得通。谢谢
标签: f# type-providers