在F中触发时未调用C#事件处理程序#

在F中触发时未调用C#事件处理程序#,c#,.net,f#,C#,.net,F#,我正在努力将一个事件从一个用F写的类中暴露给C。使用let绑定定义事件时,这没有问题: let myFSharpEvent = new Event<EventArgs>() [<CLIEvent>] member this.FSharpEvent = myFSharpEvent.Publish member this.RaiseFSharpEvent e = myFSharpEvent.Trigger e 然而,我找不到使用let绑定的方法,因为在我的真实场景中,我

我正在努力将一个事件从一个用F写的类中暴露给C。使用let绑定定义事件时,这没有问题:

let myFSharpEvent = new Event<EventArgs>()

[<CLIEvent>]
member this.FSharpEvent = myFSharpEvent.Publish

member this.RaiseFSharpEvent e = myFSharpEvent.Trigger e
然而,我找不到使用let绑定的方法,因为在我的真实场景中,我的类继承自一个用C#编写的类,并且不仅有一个默认构造函数,还有一个复制构造函数和一个我需要重写的反序列化构造函数


所以问题是:为什么let绑定可以工作,但成员不能私有。

我喜欢使用SharpLab.io快速查看一些F#如何编译成c#

//您的F#
让myFSharpEvent=新事件()
//到c#
内部FSharpEvent myFSharpEvent;
-----------
//你的F#
成员private this.myFSharpEvent=新事件()
//到c#
内部FSharpEvent myFSharpEvent
{
得到
{
返回新的FSharpEvent();
}
}
您可以看到,每次调用私有版本时,都会得到一个新的事件处理程序,然后将其丢弃给GC

我发现典型的OO内容在F#中也令人困惑,但我认为主要模式是使用let绑定作为支持字段,并用成员绑定包装它们:


问题在于,每次以成员身份访问myFsharpEvent时,您都在创建一个新实例。let绑定只创建一次


因此,当你调用Trigger时,它是一个与你正在发布的实例不同的实例,这就是为什么它要在你的c#code中提升它。

Don Syme的一个技巧是使用疯狂的名称,这样很容易找到你想要的有趣的部分:我不理解你为什么不能使用let绑定的解释。
member private this.myFSharpEvent = new Event<EventArgs>()

[<CLIEvent>]
member this.FSharpEvent = this.myFSharpEvent.Publish

member this.RaiseFSharpEvent e = this.myFSharpEvent.Trigger e
class Program
{
    static void Main(string[] args)
    {
        var fsObject = new FSharpClass();
        Console.WriteLine(fsObject.ToString());

        fsObject.FSharpEvent += FsObject_FSharpEvent;
        fsObject.RaiseFSharpEvent(EventArgs.Empty);
        fsObject.FSharpEvent -= FsObject_FSharpEvent;

        Console.ReadLine();
    }

    private static void FsObject_FSharpEvent(object sender, EventArgs args)
    {
        Console.WriteLine("F# event was raised.");
    }
}
//Your F#
let myFSharpEvent = new Event<EventArgs>()

//To c#
internal FSharpEvent<EventArgs> myFSharpEvent;

-----------

//Your F#
member private this.myFSharpEvent = new Event<EventArgs>()

//To c#
internal FSharpEvent<EventArgs> myFSharpEvent
{
    get
    {
        return new FSharpEvent<EventArgs>();
    }
}