无法在F#中使用受保护的事件 [英] Unable to use protected events in F#

查看:78
本文介绍了无法在F#中使用受保护的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下C#类

public class Class1
{
    protected event EventHandler ProtectedEvent;
    protected virtual void OverrideMe() { }
}

在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 

在此示例中,我尝试在其上调用printfn,因为有多种方法可以在F#中挂接事件,并且我想清楚一点,就是导致问题的根本原因仅仅是对事件的引用. /p>

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

一个受保护的成员被调用或正在使用"base".这只是 允许直接实施成员,因为他们可以 逃避他们的对象范围.

我了解此错误,是什么原因导致的错误及其目的.通常,解决方法是将调用包装在私有成员中,该私有成员可以很好地与方法配合使用-但似乎不适用于事件.无论我如何尝试,除非我采取反射操作或对基类进行一些更改(在我的情况下是不可能的),否则似乎无法在F#中使用受保护的事件.

请注意,我还尝试了使用basethisx的所有可能组合.

我做错什么了吗?

解决方案

我怀疑当您将事件视为稍后会混淆的一流值时,编译器会在后台生成一些有关代码的信息一些隐藏的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"

这对我来说很好.可惜您不能将保护事件用作一等值,但这至少可以让您使用它...

Let's say we have the following C# class

public class Class1
{
    protected event EventHandler ProtectedEvent;
    protected virtual void OverrideMe() { }
}

It seems to be impossible to use the ProtectedEvent in F#.

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 

In this example I have attempted to call printfn on it, as there are multiple ways to hook up events in F# and I wanted to be clear that is simply the referencing of the event at all that causes the problem.

In each of the cases above the compiler complains with the following error

A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope.

I understand this error, what causes it and its purpose. Usually, the work around is to wrap the call in a private member, which works fine with methods - but that does not seem to work with events. No matter what I try, it seems to be impossible to use protected events in F# unless I resort to doing something with reflection, or make some changes to the base class (which in my case is not possible).

Note that I have also tried all possible combinations of using base, this and x.

Am I doing something wrong ?

解决方案

I suspect that there is something about the code that the compiler generates behind the scene when you treat the event as a first-class value that later confuses it (i.e. some hidden lambda function that makes the compiler think it cannot access the protected member). I'd say that this is a bug.

As far as I can see, you can workaround it by using add_ProtectedEvent and remove_ProtectedEvent members directly (they do not show in the auto-completion, but they are there and are accessible - they are protected, but calling them is a direct method call, which is fine):

type HelpMe() =
    inherit Class1()

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

    override x.OverrideMe() =
        printfn "hello"

This compiled fine for me. It is a shame that you cannot use the protected event as a first-class value, but this at least lets you use it...

这篇关于无法在F#中使用受保护的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆