Inheritance 我可以避免为从接口派生的类编写样板代码吗?

Inheritance 我可以避免为从接口派生的类编写样板代码吗?,inheritance,interface,f#,boilerplate,Inheritance,Interface,F#,Boilerplate,我有许多实现接口的类。每当我定义一个类时,我必须在类定义中编写如下内容: interface Model.IModel with member this.Assets = modelArg.Assets member this.AuxData = modelArg.AuxData member this.Benchmark = modelArg.Benchmark member thi

我有许多实现接口的类。每当我定义一个类时,我必须在类定义中编写如下内容:

interface Model.IModel with

        member this.Assets          = modelArg.Assets
        member this.AuxData         = modelArg.AuxData
        member this.Benchmark       = modelArg.Benchmark
        member this.CalcPeriods     = modelArg.CalcPeriods
        member this.CashTicker      = modelArg.CashTicker
        member this.Description     = modelArg.Description
        member this.FirstValidDate  = modelArg.FirstValidDate
        member this.Name            = modelArg.Name
        member this.ParamData       = modelArg.ParamData
        member this.ParamList       = modelArg.ParamList
        member this.Strategy        = modelArg.Strategy

        member this.CalcStartTime with get() = calcStartTime and
                                       set v = calcStartTime <- v

        member this.Counter with get() = counter and
                                 set v = counter <- v
interface Model.IModel与
成员this.Assets=modelArg.Assets
成员this.AuxData=modelArg.AuxData
成员this.Benchmark=modelArg.Benchmark
成员this.CalcPeriods=modelArg.CalcPeriods
成员this.CashTicker=modelArg.CashTicker
成员this.Description=modelArg.Description
成员this.FirstValidDate=modelArg.FirstValidDate
成员this.Name=modelArg.Name
成员this.ParamData=modelArg.ParamData
成员this.ParamList=modelArg.ParamList
成员this.Strategy=modelArg.Strategy
使用get()=CalcStartTime和

设置v=calcStartTime以使讨论更具体一些,并且由于评论中的空间有限,下面的内容对您是否有效

 type ModelArg = {
     Number: int
     Name: string
 }

 type IModel(modelArg: ModelArg) = 
    abstract member Number: int
    abstract member Name: string
    default __.Number = modelArg.Number
    default __.Name = modelArg.Name

type ConcreteModel1(modelArg: ModelArg) =
    inherit IModel(modelArg)

type ConcreteModel2(modelArg: ModelArg) =
    inherit IModel(modelArg)

let modelArg1 = {Number=2; Name ="Joe"}
let modelArg2 = {Number=3; Name = "Jim"}

let getNumberAndName(x: IModel) =
    (x.Number, x.Name)

let model1 = ConcreteModel1(modelArg1)
let model2 = ConcreteModel2(modelArg2)

getNumberAndName(model1)
//val it : int * string = (2, "Joe")
getNumberAndName(model2)
//val it : int * string = (3, "Jim")

实现接口的基类和从该基类继承的各个实现是我能想到的唯一方法。(我有点怀疑这里更有趣的部分是更大的背景和目的,因为完全不同的方法可能更惯用F#)是的,尽可能避免类和继承是F#的一个重要目标,但作为一种多方面语言,会有使用“对象编程”的情况,正如Don Syme所说,这是必要的,或者只是更好的方式。但是你提到的事情正是我所说的,更大的背景将是这里有趣的事情,因为这可能会导致一个完全不同的设计决策。不过,我想这将是一个不同的问题,需要看到更多您可能无法共享的代码。我将尝试找出一个简单的方法来展示我正在尝试做什么,并把它放在另一个问题中。为什么你必须在每节课上都写这个?拥有一个庞大的属性列表,你需要在任何地方都包含它,这似乎是一个巨大的设计问题。为什么你不能提供一个默认的实现呢?可能吧。我试试看。三个基本问题:1)Microsoft文档说,
default
关键字“表示抽象方法的实现;与抽象方法声明一起用于创建虚拟方法。”但在这种情况下,
default
是抽象成员,而不是抽象方法。这样行吗?2) 在您的示例中,是否可以不将数字和名称作为摘要?如果是的话,把它们抽象化有什么好处吗?3) 我的类中有三个抽象方法。我是否必须用
[]
注释基类?@Soldalma 1。对2.是的,您可以创建一个包含所需逻辑的类型,并将其作为构造函数参数传递给依赖项注入,然后将整个类型作为属性公开并对其进行操作。你问题的第二部分是关于。3.使用抽象类的优点是可以混合使用实现成员和未实现成员。您还可以在以后的实现中重写这些。如果您提供的抽象成员没有默认的实现,我相信您将需要使用
[]
进行注释。好的,它成功了。淘汰了许多样板文件。谢谢