F#的类型推理失败给出了不清楚的错误



我在f#中具有以下视图modelbase,我正在尝试构建以使用wpf学习f#。

module MVVM
open System
open System.Collections.ObjectModel
open System.ComponentModel
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open System.Reactive.Linq

module Property =
    let ToName(query : Expr) = 
        match query with
        | PropertyGet(a, b, list) ->
            b.Name
        | _ -> ""
    let SetValue<'t>(obj, query : Expr<'t>, value : 't) =
        match query with
        | PropertyGet(a, b, list) ->
            b.SetValue(obj, value)
        | _ -> ()
    let GetValue<'o, 't>(obj : 'o , query : Expr<'t>) : option<'t> =
        match query with
        | PropertyGet(a, b, list) ->
            option.Some(b.GetValue(obj) :?> 't )
        | _ -> option.None
    let Observe<'t>(x: INotifyPropertyChanged) (p : Expr<'t>)  =
        let name = ToName(p)
        x.PropertyChanged.
            Where(fun (v:PropertyChangedEventArgs) -> v.PropertyName = name).
            Select(fun v -> GetValue(x, p).Value)
type ViewModelBase() =
    let propertyChanged = new Event<_, _>()
    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChanged.Publish
    abstract member OnPropertyChanged: string -> unit
    default x.OnPropertyChanged(propertyName : string) =
        propertyChanged.Trigger(x, new PropertyChangedEventArgs(propertyName))
    member x.SetValue<'t>(expr : Expr<'t>, v : 't) =
        Property.SetValue(x, expr, v)
        x.OnPropertyChanged(expr)
    member x.OnPropertyChanged<'t>(expr : Expr<'t>) =
        let propName = Property.ToName(expr)
        x.OnPropertyChanged(propName)

但是,我从编译器中获得了一个错误

Error   1   The type 'ViewModelBase' is used in an invalid way. 
A value prior to 'ViewModelBase' has an inferred type involving 
'ViewModelBase', which is an invalid forward reference. 

但是,编译器没有告诉我值prient 是问题的有害部分。由于我对F#使用的类型推断很新,所以我可能会缺少一个明显的问题。

fyi该代码应像以下内容一样使用,但是目前该代码已评论,错误仅与上面的核心代码有关

type TestModel() as this = 
    inherit MVVM.ViewModelBase()
    let mutable name  = "hello"
    let subscription = (Property.Observe this  <@ this.SelectedItem @>).
            Subscribe(fun v -> Console.WriteLine "Yo")
    member x.SelectedItem 
        with get() = name
        and set(v) = 
            x.SetValue(<@ x.SelectedItem @>, v)

我找到了它。

let SetValue<'t>(obj, query : Expr<'t>, value : 't) =
    match query with
    | PropertyGet(a, b, list) ->
        b.SetValue(obj, value)
    | _ -> ()

受到约束。应该是

let SetValue<'t>(obj : Object, query : Expr<'t>, value : 't) =
    match query with
    | PropertyGet(a, b, list) ->
        b.SetValue(obj, value)
    | _ -> ()

最新更新