财产'背景'是F#中的静态错误

时间:2016-06-17 19:39:51

标签: c# f# static-members akka.net

我有一个问题,就是将C#中的Akka.Net演员重写为F#:

public class Listener : ReceiveActor
{
    public Listener()
    {
        Receive<Messages.Shutdown>(s =>
        {
            Console.WriteLine($"shutdown {s.Duration}");
            Context.System.Terminate();
        });
    }
}

Actor应该通过终止actor系统来处理Shutdown消息。我试图像这样重新实现它:

type Listener() =
    inherit ReceiveActor()
    do
        base.Receive<Messages>(fun m -> 
            match m with 
            | Shutdown(duration) -> 
                printf "shutdown %s" (duration.ToString())
                base.Context.System.Terminate()
                true
            | _ -> false)

base.Context.System.Terminate()Property 'Context' is static中存在编译错误。这段代码有什么问题?为什么我不能访问基类的静态属性?是因为这段代码是lambda expresion(有趣)吗?或者因为它在构造函数中(do)?

2 个答案:

答案 0 :(得分:5)

你可以这样写:

type Listener() =
    inherit ReceiveActor()
    do
        base.Receive<Messages>(fun m -> 
            match m with 
            | Shutdown(duration) -> 
                printf "shutdown %s" (duration.ToString())
                ReceiveActor.Context.System.Terminate()
                true
            | _ -> false)

请注意,您可以使用function代替match ... with

        base.Receive<Messages>(function 
            | Shutdown(duration) -> 

然后printfn相当于WriteLine,而且:

printfn "shutdown %s" (duration.ToString())

与:

相同
printfn "shutdown %O" duration

<强>更新

如果您的错误消息显示为静态属性,则无法在lambda中使用该属性,对于该问题,请参阅this已回答的问题。

答案 1 :(得分:4)

想出来。问题是:

  1. 我使用了错误的语法来访问基类的静态成员。正如@ildjarn所评论的那样,它应该是ReceiveActor.Context,而不是base.Context

  2. 无法从lambda表达式访问受保护的成员。处理程序需要是成员方法。

  3. 工作版:

    type Listener() as this =
        inherit ReceiveActor()
        do
            base.Receive<Messages>(this.handle)
    
        member this.handle(message: Messages): bool = 
            match message with 
            | Shutdown(duration) -> 
                printf "shutdown %s" (duration.ToString())
                ReceiveActor.Context.System.Terminate()
                true
            | _ -> false
    

    重要更改:1。as this让我们从构造函数调用成员方法,2。编译器需要在handle方法中键入注释以解决Receive方法重载歧义。