无法在F#中使用受保护的事件

Ros*_*lay 5 f#

假设我们有以下C#类

public class Class1
{
    protected event EventHandler ProtectedEvent;
    protected virtual void OverrideMe() { }
}
Run Code Online (Sandbox Code Playgroud)

似乎不可能在F#中使用ProtectedEvent.

type HelpMe() as this =
    inherit Class1()

    do
        printfn "%A" this.ProtectedEvent        

    member x.HookEvents() =
        printfn "%A" x.ProtectedEvent

    member private x.HookEvents2() =
        printfn "%A" x.ProtectedEvent 

    override x.OverrideMe() =
        printfn "%A" x.ProtectedEvent 
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我试图调用printfn它,因为有多种方法可以在F#中连接事件,我希望很清楚,这只是导致问题的事件的引用.

在上面的每种情况下,编译器都会抱怨以下错误

被调用的受保护成员或正在使用"基础".这只能在成员的直接实现中使用,因为它们可以逃避它们的对象范围.

我理解这个错误,是什么导致它及其目的.通常,解决方法是将调用包装在私有成员中,该方法适用于方法 - 但这似乎不适用于事件.无论我尝试什么,似乎都不可能在F#中使用受保护的事件,除非我求助于使用反射做某事,或者对基类做一些更改(在我的情况下是不可能的).

请注意,我也尝试了所有可能的使用组合base,thisx.

难道我做错了什么 ?

Tom*_*cek 3

我怀疑,当您将事件视为一等值时,编译器在幕后生成的代码中存在某些内容,这些代码后来会混淆它(即某些隐藏的 lambda 函数使编译器认为它无法访问受保护的成员)。我想说这是一个错误。

据我所知,您可以通过直接使用add_ProtectedEventremove_ProtectedEvent成员来解决它(它们不会显示在自动完成中,但它们在那里并且可以访问 - 它们受到保护,但调用它们是直接方法调用,这是美好的):

type HelpMe() =
    inherit Class1()

    member x.HookEvents() =
        let eh = System.EventHandler(fun _ _ -> printfn "yay")
        x.add_ProtectedEvent(eh)

    override x.OverrideMe() =
        printfn "hello"
Run Code Online (Sandbox Code Playgroud)

这对我来说编译得很好。遗憾的是您不能将受保护的事件用作一流值,但这至少可以让您使用它......