具有多个构造函数语法的F#继承

时间:2018-06-29 03:57:41

标签: inheritance constructor f#

我有这个F#课

module File1

open System
open System.Collections.Generic

type TimeRangeList<'e>(getter: DateTime * DateTime -> List<'e>, ?maybe_tFrom: DateTime, ?maybe_tTo: DateTime) as this = 
    inherit List<'e>()
    //inherit List<'e>(getter(defaultArg maybe_tTo DateTime.Now, defaultArg maybe_tFrom ((defaultArg maybe_tTo DateTime.Now).AddDays(-1.0))))

    let tTo = defaultArg maybe_tTo DateTime.Now
    let tFrom = defaultArg maybe_tFrom (tTo.AddDays(-1.0))
    do this.AddRange(getter(tFrom, tTo))

现在我想添加构造函数并使用here

中的语法
type TimeRangeList<'e> = 
    inherit List<'e>
    val tFrom: DateTime
    val tTo: DateTime
    new (getter: DateTime * DateTime -> List<'e>, ?maybe_tFrom: DateTime, ?maybe_tTo: DateTime) = {
            inherit List<'e>()
            //inherit List<'e>(defaultArg maybe_tFrom ((defaultArg maybe_tTo DateTime.Now).AddDays(-1.0)), getter(defaultArg maybe_tTo DateTime.Now))

            tTo = defaultArg maybe_tTo DateTime.Now
            tFrom = defaultArg maybe_tFrom (tTo.AddDays(-1.0)) //tTo undefined
            //tFrom = defaultArg maybe_tFrom ((defaultArg maybe_tTo DateTime.Now).AddDays(-1.0))
        }
    do this.AddRange(getter(tFrom, tTo)) //primary constructor required

此代码给出两个错误:

  1. 在“ tFrom = ...”中显示“ tTo未定义”,而tTo显然位于 范围;作为解决方法,我可以重复defaultArg调用,如下所示 以下(注释)行。有更好的方法吗?
  2. 在调用“ AddRange”的最后一行中,它抱怨do调用只能在主构造函数中执行,这很公平。但是,如何调用必要的AddRange来初始化列表?我尝试了其他选项,但找不到路。注释后的继承行中显示了一种解决方法,但最后,我反复重复地调用了defaultArg;必须有一种更清晰,更优雅的方式

2 个答案:

答案 0 :(得分:5)

这是您要查找的语法:

module File1

open System
open System.Collections.Generic

type TimeRangeList<'e> = 
    inherit List<'e>
    val tFrom: DateTime
    val tTo: DateTime
    new (getter: DateTime * DateTime -> List<'e>, ?maybe_tFrom: DateTime, ?maybe_tTo: DateTime) as this =
        let to_ = defaultArg maybe_tTo DateTime.Now
        let from_ = defaultArg maybe_tFrom (to_.AddDays(-1.0))
        {
            inherit List<'e>()

            tTo = to_
            tFrom = from_
        }
        then
            this.AddRange(getter(this.tFrom, this.tTo))

文档链接:

稍微说明一下,{ field = value; field2 = value2 }语法不必是在定义辅助构造函数的new()块中找到的仅 表达式。它仅是 last 表达式,即返回的表达式。 (在这里,即使从技术上讲,then块是构造函数中的“最后一个”块,但其返回值(必须为unit)将被忽略,构造函数的实际返回值为在then块中找不到最后一个表达式 )。因此,较早使用let表达式来定义要放入类字段中的值是安全的,并且这些let表达式可以像在普通代码中那样相互引用。因此,如果您需要将复杂的计算或昂贵的计算放入几个字段中,则可能会发生以下情况:

new () =
    let result = expensiveCalculationIWantToDoOnlyOnce()
    { field1 = result; field2 = result + 1; field3 = result + 2 }

答案 1 :(得分:1)

要解决第一个问题,应为当前对象命名:new (...) as this =,然后使用其this.tTo.AddDays(-1.0)访问变量。

第二个问题我还没有解决办法。