代码之家  ›  专栏  ›  技术社区  ›  Franco Tiveron

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

  •  3
  • Franco Tiveron  · 技术社区  · 7 年前

    我有这个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 回复  |  直到 7 年前
        1
  •  5
  •   rmunn    7 年前

    这是您要查找的语法:

    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 } 语法不一定是 只有 在中找到的表达式 新建() 定义辅助构造函数的块。它必须是 最后的 表达式,即返回的表达式。(在这里,尽管技术上 然后 块是构造函数中的“最后一个”块,其返回值(需要 unit )被忽略,构造函数的实际返回值是最后一个表达式 在中找不到 然后 )。因此,使用它是安全的 let 前面定义要放入类字段中的值的表达式,以及 表达式可以像在普通代码中那样互相引用。因此,如果您需要将一个复杂或昂贵的计算放入多个字段中,那么可以这样做:

    new () =
        let result = expensiveCalculationIWantToDoOnlyOnce()
        { field1 = result; field2 = result + 1; field3 = result + 2 }
    
        2
  •  1
  •   Thomas Corbière    7 年前

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

    我还没有第二个问题的解决方案。