Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#用于实现'的语法;虚拟';实现接口的属性_F#_C# To F# - Fatal编程技术网

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

F#用于实现'的语法;虚拟';实现接口的属性,f#,c#-to-f#,F#,C# To F#,我需要在基类中实现接口。接口需要属性和索引器。我想为两者提供一个默认实现,并允许子类重写它。我似乎无法使用“虚拟”实现的语法和接口实现的语法!例如: type ViewModelBase() = interface IDataErrorInfo with abstract Error : string with get default this.Error with get() = "" 给出以下编译错误 错误1成员定义中出现意外的关键字“abstrac

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

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


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

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

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

要使用虚拟实现实现IDataErrorInfo和InotifyProperty更改,请执行以下代码:

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)
键入ViewModelBase()=
让propertyChangedEvent=new DelegateEvent()
抽象错误:带有get的字符串
默认情况下,get()为“”时出错
抽象项:字符串->带get的字符串
默认情况下,此项的get(name)=“”
接口INotifyProperty更改为
[]
成员x.PropertyChanged=propertyChangedEvent.Publish
成员x.OnPropertyChanged propertyName=
触发器([| x;新的PropertyChangedEventArgs(propertyName)|])
IDataErrorInfo与的接口
//传递到虚拟财产实现
成员this.Error=this.Error
使用get(x)成员this.Item=this.Item(x)
通常可以用来代替抽象类和虚拟方法。您可以通过提供给“工厂”函数的参数来控制行为。大概是这样的:

类型IMyInterface=
抽象SayHello:unit->string
抽象项:字符串->带get的obj
让makeMyInterface说你好(查找:IDictionary)=
{与的新IMyInterface
成员x.SayHello()=SayHello()
成员十项目
使用get name=lookup.[name]}

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

我喜欢对象表达式。它们使游戏脚本编写变得非常简单。它们还避免了显式接口实现所需的复制和强制转换。我认为这不适合我的情况。我的框架(WPF)需要实现接口的类。我认为我不能通过另一个实现IDataErrorInfo的类来代替我的视图模型。如果可以使用对象表达式来解决我的问题,那么这不是有效的混合/多重继承吗?我认为F#不允许你这么做?不过,对象表达式实际上会在其他地方对我有所帮助,谢谢你的发帖。