f# - 无法在 F# 中使用 protected 事件

标签 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# 中连接事件,我想明确一点,这仅仅是导致问题的事件的引用。

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

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.



我理解这个错误,是什么原因造成的以及它的目的。通常,解决方法是将调用包装在私有(private)成员中,这适用于方法 - 但这似乎不适用于事件。无论我尝试什么,似乎都不可能在 F# 中使用 protected 事件,除非我诉诸反射来做一些事情,或者对基类进行一些更改(在我的情况下这是不可能的)。

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

难道我做错了什么 ?

最佳答案

我怀疑当您将事件视为一等值时,编译器在幕后生成的代码有些东西后来混淆了它(即一些隐藏的 lambda 函数使编译器认为它无法访问 protected 成员)。我会说这是一个错误。

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

type HelpMe() =
    inherit Class1()

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

    override x.OverrideMe() =
        printfn "hello"

这对我来说很好。遗憾的是,您不能将 protected 事件用作一等值,但这至少可以让您使用它......

关于f# - 无法在 F# 中使用 protected 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27678503/

相关文章:

function - F# 纯函数和柯里化(Currying)

asp.net - 使用 f#/fable/asp.net/react 添加 google 登录按钮

f# - 使用 FParsec 解析 float 或 int*float

recursion - 抽象循环

f# - 内联和运算符重载问题

f# - F# 中的 AutoOpen 属性

unit-testing - 在哪里可以找到大量用于单元测试的 YAML 文件?

f# - F# Interactive 中的 StructLayout 限制?

generics - 向量运算的 F# 类型约束

mysql - 从 App.config F# AppSettings 提供程序获取和使用连接字符串