3

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

type ViewModelBase() =
  interface IDataErrorInfo with
    abstract Error : string with get
    default this.Error with get() = ""

给出以下编译错误

错误 1 ​​成员定义中出现意外的关键字“抽象”。预期的“成员”、“覆盖”或其他标记。D:\MinorApps\VetCompass\VetCompass\ViewModel\ViewModelBase.fs 18 7 VetCompass

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

我什至不知道从哪里开始索引器!

4

3 回答 3

8

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

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
于 2012-10-12T14:06:58.470 回答
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] }

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

于 2012-10-12T16:43:23.173 回答
0

要使用虚拟实现来实现 IDataErrorInfo 和 INotifyPropertyChanged,代码如下:

type ViewModelBase() =
    let propertyChangedEvent = new DelegateEvent<PropertyChangedEventHandler>()

    abstract Error : string with get
    default this.Error with get() = ""

    abstract Item : string -> string with get
    default this.Item with get(name) = ""

    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChangedEvent.Publish
    member x.OnPropertyChanged propertyName = 
        propertyChangedEvent.Trigger([| x; new PropertyChangedEventArgs(propertyName) |])

    interface IDataErrorInfo with
       // pass through to the virtual property implementation
       member this.Error = this.Error
       member this.Item with get(x) = this.Item(x)
于 2012-10-12T14:34:57.953 回答