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

标签 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;一定有更清晰更优雅的方式

最佳答案

这是您正在寻找的语法:

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() block 中找到的唯一表达式。它必须是 last 表达式,即返回的表达式。 (这里,即使从技术上讲 then block 是构造函数中的“最后一个” block ,它的返回值(必须是 unit)被忽略并且实际返回构造函数的值是最后一个表达式then block 中找不到)。因此,较早使用 let 表达式来定义要放入类字段的值是安全的,并且这些 let 表达式可以像在正常情况下一样相互引用代码。因此,如果您需要在多个字段中进行复杂或昂贵的计算,您可以这样做:

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

关于inheritance - 具有多个构造函数语法的 F# 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51094049/

相关文章:

java - 如何在实现接口(interface)但不扩展另一个类的 Java 类中引用 super 方法?

c# - 自定义控件是否继承基类 INotifyPropertyChanged 接口(interface)?

c# - 我 = 对象 (C# : This = object)

java - 抽象方法和扩展方法中的构造函数

f# - if-then 语句的功能替代是什么?

javascript - 一个构造函数的属性是否可以被另一个构造函数继承?

C++17:始终调用用户定义的构造函数并且 operator+ 重载不适用于子类

php - 需要帮助修复将生成 radio 组的类

f# - 具有Powerpack 2.0的F#2.0,fslex错误1

f# - 内联时扩展方法出错