Mvvm 是否可以在F中将INotifyPropertyChanged实现为类型扩展#

Mvvm 是否可以在F中将INotifyPropertyChanged实现为类型扩展#,mvvm,f#,extension-methods,inotifypropertychanged,Mvvm,F#,Extension Methods,Inotifypropertychanged,在C#中,您可以实现基于PropertyChangedEventHandler的扩展方法,如下所示: static class VMExts { public static void RaisePropertyChanged(this PropertyChangedEventHandler handler, object sender, string propName) { if(handler != null) { handler

在C#中,您可以实现基于PropertyChangedEventHandler的扩展方法,如下所示:

  static class VMExts
  {
    public static void RaisePropertyChanged(this PropertyChangedEventHandler handler, object sender, string propName)
    {
      if(handler != null)
      {
        handler(sender, new PropertyChangedEventArgs(propName));
      }
    }
  }
  class VM : INotifyPropertyChanged
  {
    private string _someText;

    public event PropertyChangedEventHandler PropertyChanged;

    public string SomeText
    {
      get { return _someText; }
      set
      {
        _someText = value;
        PropertyChanged.RaisePropertyChanged(this, "SomeText");
      }
    }
  }
可称之为:

  static class VMExts
  {
    public static void RaisePropertyChanged(this PropertyChangedEventHandler handler, object sender, string propName)
    {
      if(handler != null)
      {
        handler(sender, new PropertyChangedEventArgs(propName));
      }
    }
  }
  class VM : INotifyPropertyChanged
  {
    private string _someText;

    public event PropertyChangedEventHandler PropertyChanged;

    public string SomeText
    {
      get { return _someText; }
      set
      {
        _someText = value;
        PropertyChanged.RaisePropertyChanged(this, "SomeText");
      }
    }
  }
我一直试图在F#中实现类似的功能,但无法理解语法。 显然,通过继承一些ViewModelBase样式的类(如)很容易实现这一点,但是如果有一个扩展方法就更好了

因此,考虑到这一类:

键入ViewModelBase()=
让可变的_someText=“”
让propertyChanged=事件()
接口INotifyProperty更改为
[]
成员x.PropertyChanged=PropertyChanged.Publish
成员x.SomeText
使用get()=\u someText
和设置(值)=
_someText INotifyPropertyChanged).PropertyChanged.RaisePropertyChanged(“someText”)
我试过:

使用
成员x.RaisePropertyChanged(发送方,propName)=
如果x为空,则
x、 调用(发送方,PropertyChangedEventArgs(propName))

open System.Runtime.CompilerServices
[]
类型VmExtensions()=
[]  
静态成员内联RaisePropertyChanged(处理程序:PropertyChangedEventHandler,propName)=
如果处理程序为null,则
调用(handler,PropertyChangedEventArgs(propName))
我认为这些属性对于PropertyChanged是无效的,因为PropertyChanged的类型是IEEvent,而我扩展了PropertyChangedEventHandler类型

因此,我尝试:

使用
成员x.RaisePropertyChanged(发送方,propName)=
如果x为空,则
x、 调用(发送方,PropertyChangedEventArgs(propName))
但是编译器不喜欢IEvent的用法
[]
类型VmExtensions()=
[]  
静态成员内联RaisePropertyChanged(处理程序:IEvent,propName)=
//如果处理程序为null,则
调用(handler,PropertyChangedEventArgs(propName))
但是IEvent实际上只有一个Subscribe方法


谢谢

您可以通过
触发器
方法引发事件,该方法在
事件
上定义(而不是在
事件
上定义):

[]
类型VmExtensions=
[]  
静态成员内联RaisePropertyChanged
(ev:事件、名称)=
ev.Trigger(null,PropertyChangedEventArgs propName)

啊,是的,很有效,谢谢。很遗憾,我需要强制转换在PropertyChanged.Publish中创建的IEvent。我需要在RaisePropertyChanged函数中执行此操作,并在强制转换失败时引发异常,或者,在我使用INotifyPropertyChanged的任何地方都执行此操作。很高兴您找到了有效的方法。那你能核对一下答案吗。另一方面,我真的不明白你为什么要使用一种方法,首先需要从
IEvent<,>
Event<,>
进行转换。避免重复执行
INotifyPropertyChanged
的通常解决方案是简单地从
ViewModelBase
类继承,该类定义了某种(内部)
OnNotivyPropertyChanged
方法,继承者可以调用该方法。这不是“惯用的功能性”F#,但从语用的角度来看,它完全可以。是的,你是对的。我忘了我已经创建了这个活动,并且可以访问它,所以我关于演员的观点是无关紧要的。利用这一点,我提出了一些我非常喜欢的实现。