我正在尝试将一些现有代码重构为更单一的方法。现有代码包含接口IXInterface
和数字,例如int
和bool
。默认情况下,数字已经具有Zero
,接口将其作为属性获取器,但bool
并string
没有。一种方法是将 bool 和 string 包装在一个接口中,但这很麻烦。
我想如果 F# 语言能够扩展数字类型,也许我也可以针对我的特定情况对字符串和布尔值进行扩展。
module MyZero =
let inline get_zero () : ^a = ((^a) : (static member get_Zero : unit -> ^a)())
type System.String with
static member get_Zero() = System.String.Empty
type XR<'T when 'T : (static member get_Zero : unit -> 'T)> =
| Expression of (SomeObj -> 'T)
| Action of (int -> 'T)
| Value of 'T
| Empty
member inline this.Execute(x: SomeObj) : 'T =
match this with
| Value(v) -> v
| Expression(ex) -> ex x
| Action(a) -> a x.GetLocation
| Empty -> get_zero()
static member map f x=
match x with
| XR.Empty -> XR.Empty
| XR.Value v -> XR.Value <| f v
| XR.Action p -> XR.Action <| fun v -> f (p v)
| XR.Expression e -> XR.Expression <| fun x -> f (e x)
// etc
上面的编译很好,只要我不尝试将它与字符串或布尔值一起使用:
type WihtBool = XR<int> // succeeds
type WihtBool = XR<IXInterface> // succeeds
type WihtBool = XR<bool> // fails
type WithString = XR<string> // fails
错误是明确和正确的(我有一个扩展方法,由于明显的原因无法识别),我只是不知道一种非侵入性的方法来摆脱它:
失败并显示“类型 bool 不支持运算符 'get_Zero'
失败并显示”类型字符串不支持运算符 'get_Zero'