用于实现实现接口的"虚拟"属性的F#语法

Noe*_*edy 2 f# c#-to-f#

我需要在基类中实现IDataErrorInfo接口.该接口需要属性和索引器.我想为两者提供默认实现,并允许子类覆盖它.我似乎无法使用接口实现的语法来实现"虚拟"实现的语法!例如:

type ViewModelBase() =
  interface IDataErrorInfo with
    abstract Error : string with get
    default this.Error with get() = ""
Run Code Online (Sandbox Code Playgroud)

给出以下编译错误

错误1成员定义中的意外关键字'abstract'.预期的"会员","覆盖"或其他令牌.D:\ MinorApps\VetCompass\VetCompass\ViewModel\ViewModelBase.fs 18 7 VetCompass

错误2模式D中此点或之前的不完整结构化构造:\ MinorApps\VetCompass\VetCompass\ViewModel\ViewModelBase.fs 19 7 VetCompass

我甚至不确定从哪里开始索引器!

kvb*_*kvb 6

所有接口实现都是显式的,这意味着当作为类的成员查看时,接口的方法将是私有的.因此,您不能在实现中使用abstractdefault修饰符.相反,您需要添加一些重复:

type ViewModelBase() =
    // declare a new virtual property
    abstract Error : string
    default this.Error = ""

    interface IDataErrorInfo with
       // pass through to the virtual property implementation
       member this.Error = this.Error
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 5

通常可以使用对象表达式来代替抽象类和虚方法.您可以通过提供给"工厂"功能的参数来控制行为.像这样的东西:

type IMyInterface =
  abstract SayHello : unit -> string
  abstract Item : string -> obj with get

let makeMyInterface sayHello (lookup: IDictionary<string, obj>) =
  { new IMyInterface with
      member x.SayHello() = sayHello()
      member x.Item 
        with get name = lookup.[name] }
Run Code Online (Sandbox Code Playgroud)

这可能不适用于您的情况,因为您受到现有框架约定的约束.但在某些情况下它可能是一个不错的选择.