类型提供程序中的奇怪的无行为 [英] Weird None behaviour in type providers

查看:66
本文介绍了类型提供程序中的奇怪的无行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个类型提供程序,其类型分别为'string','string option'和'int option'的三个属性'a','b'和'c'.

have a type provider with three properties 'a', 'b', and 'c' of type 'string', 'string option' and 'int option', respectively.

当我的实例的属性中包含",无"和"1"时,此操作将失败:

When I have an instance with "", None, and Some 1 in those properties, this fails:

(row1.a, row1.b, row1.c) |> should equal ("", None, Some 1)

但是所有这些都可以正常工作:

But all of these work fine:

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有所不同?编译后,无"只是一个空值,.Net中的两个空值可以不同吗?

How is this possible? What can make the None in b be different from any other None? After compilation, None is just a null, can two null values be different in .Net?

像大多数F#类型一样,Tuples具有结构上的相等性,因此它应该起作用. 我收到带有消息的NUnit.Framework.AssertionException:

Tuples have structural equality, like most F# types, so it should work. I get an NUnit.Framework.AssertionException with Message:

Expected: <(, , Some(1))>
But was:  <(, , Some(1))>

NUnit只是调用.Equals,所以问题就出在这里.

NUnit just calls .Equals, so that's where the problem is.

这也会失败:

(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>>,因此即使在理论上也应如此:

The runtime type of row1 is System.Tuple<string,Microsoft.FSharp.Core.FSharpOption<string>,Microsoft.FSharp.Core.FSharpOption<int>>, so even this should work in theory:

row1 |> should equal ("", None, Some 1)

实际上,当元组中没有None时,它就会这样做.

And in fact it does when there's no None in the tuple.

除了类型提供程序外,我无法用其他任何方式重现此行为.

I can't reproduce this behaviour with anything else but type providers.

推荐答案

我们被这个问题咬了好几次,所以我们创建了

We have been bitten by this several times, so we create a specific note on this:

FsUnit使用类型测试来实现其DSL.类型推断不适用于此DSL,因此请确保两个比较值属于同一类型.

FsUnit uses type test to implement its DSL. Type inference doesn't work on this DSL, so make sure that two compared values belong to the same type.

例如,对于某些通用值,例如TrueFalse等,您需要指定其类型(如formula<fol>.Trueformula<fol>.False等),否则将这些值作为类型进行比较obj.

For example, for some generic values such as True, False, etc, you need to specify their types (as formula<fol>.True, formula<fol>.False, etc) otherwise these values will be compared as being of type obj.

如果您查看如何实现FsUnit,它不是真正的类型安全的.我相信杰克P.的拉取请求是朝着使FsUnit更加类型安全的方向迈出的一步.这似乎是需要改进FsUnit的领域.

If you take a look at how FsUnit is implemented, it isn't really type-safe. I believe Jack P.'s pull request is a step towards making FsUnit more type-safe. It seems to be an area to improve FsUnit.

这篇关于类型提供程序中的奇怪的无行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆