在F中触发时未调用C#事件处理程序#
我正在努力将一个事件从一个用F写的类中暴露给C。使用let绑定定义事件时,这没有问题:在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绑定的方法,因为在我的真实场景中,我
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>();
}
}