我有一个这样定义的类类型:
type T1(?maybei1: int, ?maybei2: int) =
以下所有工作:
let t11 = T1(1, 2)
let t12 = T1(1)
let t13 = T1()
但是这个(没有预期):
let tuple = (1, 2)
let t14 = T1 tuple //error: expected int but given int * int
另一方面,如果我将类型定义为:
type T2(i1: int, i2: int) =
然后我可以用元组构造一个实例
let tuple = (1, 2)
let t24 = T2 tuple //ok
但是我丢失了可选项:
let t22 = T2(1) //error
let t23 = T2() //error
我尝试了其他构造函数:
type T3(?maybei1: int, ?maybei2: int) =
new (i1: int, i2: int) = T3(i1, i2)
type T4(i1: int, i2: int) =
new (?maybei1: int, ?maybei2: int) =
但是我没有一个可以同时使用可选参数和元组实例化的版本。 有什么想法(没有委派,封装或继承,只有一种类型)?
编辑
Tomas Petricek找到了使其工作的方法;足够好。
但是,正如他还提到的那样,恕我直言,有些事情听起来并不完全正确。 例如,如果没有使用元组的重载构造函数,我们最终会遇到以下情况:
let tup = (1, 2)
let t1 = T (1, 2) //ok
let t2 = T tup //error
在第一个实例化中,编译器将两个参数映射为构造函数所期望的选项类型,我希望在第二个实例化中也会发生相同的情况。 有谁知道不是这样的原因吗?
答案 0 :(得分:8)
如果添加一个重载的构造函数,该构造函数将显式元组作为唯一参数,那么创建实例的所有方法都可以工作:
type T(?maybei1: int, ?maybei2: int) =
new (tup:int*int) = T(fst tup, snd tup)
member x.Values = maybei1, maybei2
T(1)
T(1, 2)
T(maybei2=2)
let tup = (1, 2)
T tup
老实说,我不完全确定将元组作为多个参数的方法的参数传递的规则是什么-这有些棘手。从逻辑上讲,您可以将成员视为一个元组,但是由于可选参数和编译(它作为常规方法进行编译),因此这还不是全部内容,因此行为有些微妙。但是,定义一个采用元组的显式重载(将编译为采用System.Tuple
)就可以了!