我需要在基类中实现IDataErrorInfo接口。该接口需要属性和索引器。我想为两者提供默认实现,并允许子类覆盖它。我似乎无法使用接口实现的语法来实现“虚拟”实现的语法!例如:
type ViewModelBase() =
interface IDataErrorInfo with
abstract Error : string with get
default this.Error with get() = ""
给出以下编译错误
错误1成员定义中的意外关键字'abstract'。预期 '成员','覆盖'或其他 令牌。 D:\ MinorApps \ VetCompass \ VetCompass \ ViewModel \ ViewModelBase.fs 18 7 VetCompass
错误2此时或之前的结构不完整的构造 模式D:\ MinorApps \ VetCompass \ VetCompass \ ViewModel \ ViewModelBase.fs 19 7 VetCompass
我甚至不确定从索引器开始的位置!
答案 0 :(得分:6)
所有接口实现都是显式的,这意味着当作为类的成员查看时,接口的方法将是私有的。因此,您无法在实现中使用abstract
和default
修饰符。相反,您需要添加一些重复:
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
答案 1 :(得分:5)
Object expressions来代替抽象类和虚方法。您可以通过提供给“工厂”功能的参数来控制行为。像这样:
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] }
这可能不适用于您的情况,因为您受到现有框架约定的约束。但在某些情况下它可能是一个不错的选择。
答案 2 :(得分: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)