gpt4 book ai didi

f# - F# 中的接口(interface)和抽象类

转载 作者:行者123 更新时间:2023-12-03 09:50:36 25 4
gpt4 key购买 nike

我正在尝试在 F# 中创建一小段代码。我的想法是我将有一个定义一些方法、属性和事件的接口(interface)。使用这个接口(interface),我想定义一个抽象类(具有泛型类型),它将实现一些属性/方法,但不是接口(interface)中定义的所有成员。定义所有成员的责任将在派生类上。

到目前为止,我坚持使用接口(interface)和抽象类。我遇到的问题:

  • 抽象类定义无法识别接口(interface)定义
  • 我不知道如何定义抽象类中接口(interface)的抽象成员

  • 接口(interface)编译良好,但抽象类有几个错误。消息包含在代码中

    感谢所有评论、更正、提示等。由于这是我在 F# 上的第一次试验,可能有很多错误需要指出。

    我到目前为止的代码

    接口(interface)定义
    namespace A
    type IValueItem =
    interface
    [<CLIEvent>]
    abstract member PropertyChanged :
    Control.IEvent<System.ComponentModel.PropertyChangedEventHandler,
    System.ComponentModel.PropertyChangedEventArgs>

    abstract ConvertedX : double with get, set

    abstract Y : double with get, set

    abstract member CreateCopy : obj

    abstract member NewTrendItem : obj
    end

    和抽象类
    namespace A
    [<AbstractClass>]
    type ValueItem<'TX>() =

    [<DefaultValue>]
    val mutable _y : double

    let _propertyChanged = new Event<_>()

    // ERROR: This type is not an interface type
    // ERROR: The type 'obj' is not an interface type
    // ERROR: The type 'IValueItem' is not defined
    interface IValueItem with

    // ERRROR No abstract or interface member was found that corresponds to this override
    [<CLIEvent>]
    member this.PropertyChanged :
    Control.IEvent<System.ComponentModel.PropertyChangedEventHandler,
    System.ComponentModel.PropertyChangedEventArgs>
    = _propertyChanged.Publish

    // This definition is incomplete, should be abstract
    member ConvertedX : double with get, set

    // ERROR: Incomplete structured construct at or before this point in pattern
    member CreateCopy() : obj

    member NewTrendItem() : obj

    abstract X : 'TX with get, set

    member this.Y
    with get() = this._y
    and set(value) =
    if this._y <> value then
    this._y <- value
    this.NotifyPropertyChanged("Y")

    member this.NotifyPropertyChanged(propertyName) =
    this.PropertyChanged.Trigger(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName))

    最佳答案

    The abstract class definition does not recognize the interface definition



    接口(interface)必须是 declared above抽象类,或者:在引用的项目/程序集中,在当前文件上方的文件中(文件顺序很重要),或在同一文件中。

    I'm not sure how to define the abstract members for the interface in the abstract class



    不幸的是,我们必须实现接口(interface)的所有成员,以保持您想要的行为,您可以让实现调用具有相同签名的类的抽象成员:
    type IValueItem =
    [<CLIEvent>]
    abstract PropertyChanged :
    Control.IEvent<System.ComponentModel.PropertyChangedEventHandler,
    System.ComponentModel.PropertyChangedEventArgs>

    abstract ConvertedX : double with get, set

    abstract Y : double with get, set

    abstract CreateCopy : obj

    abstract NewTrendItem : obj

    [<AbstractClass>]
    type ValueItem<'TX>() =
    let mutable y = 0.0

    let propertyChanged = Event<_, _>()

    interface IValueItem with

    [<CLIEvent>]
    member __.PropertyChanged : Control.IEvent<_, _> = propertyChanged.Publish

    member this.ConvertedX
    with get() = this.ConvertedX
    and set(x) = this.ConvertedX <- x

    member this.CreateCopy = this.CreateCopy
    member this.NewTrendItem = this.NewTrendItem

    member this.Y
    with get() = this.Y
    and set(y) = this.Y <- y

    abstract ConvertedX : double with get, set
    abstract CreateCopy : obj
    abstract NewTrendItem : obj

    member this.Y
    with get() = y
    and set(value) =
    if y <> value then
    y <- value
    this.NotifyPropertyChanged("Y")

    abstract X : 'TX with get, set

    member this.NotifyPropertyChanged(propertyName) =
    propertyChanged.Trigger(this, System.ComponentModel.PropertyChangedEventArgs(propertyName))
    Y属性被定义了两次,起初看起来有点奇怪。接口(interface)实现依赖于类的实现——这意味着访问 Y您不需要将类的实例向上转换到接口(interface),我这样做是为了保持与您的初始示例相同的行为

    给您的评论:

    要在抽象类上获取虚拟成员,您需要将成员声明为抽象并提供默认实现,下面是一个匹配注释中代码的示例:
    type IValueItem =
    abstract NewTrendItem : unit -> obj

    [<AbstractClass>]
    type ValueItem<'TX>() =
    interface IValueItem with
    member this.NewTrendItem() = this.NewTrendItem()

    abstract NewTrendItem : unit -> obj
    default __.NewTrendItem() = null

    type NumberItem() =
    inherit ValueItem<double>()

    override __.NewTrendItem() = new NumberItem() :> obj

    通常 OO F# 用于与 .NET 世界的其他部分进行交互——这里看起来就是这种情况。但是,如果代码不与另一个需要 OO 接口(interface)的 .NET API 交互,您可能会发现使用函数式方法对问题进行建模可能会产生一些更简洁的代码。 F# 中的 OO 可能不会给人最初对该语言的良好印象(尽管我个人非常喜欢它的明确性和简洁性)

    关于f# - F# 中的接口(interface)和抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37632458/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com