如何在F#代码中使用微软Coyote--在父类型中保护嵌套属性类型。

问题描述 投票:1回答:1

这里是否有F#和C#的语言差异,阻碍了微软Coyote在F#代码中的使用?

因为 OnEventDoActionAttribute 是在继承类型中定义的 Microsoft.Coyote.Actors.Actor 使用受保护的访问修饰符,看起来在C#中它仍然可以在继承的actor类型中访问,但在F#中却不是这样。

Hello world示例转换为F#。

type SetupEvent(serverId : ActorId) =
    inherit Event()
    member this.ServerId = serverId

type PingEvent(callerId : ActorId) = 
    inherit Event()
    member this.Caller = callerId

type PongEvent() =
    inherit Event()

// both attribute spec fail
//[<Microsoft.Coyote.Actors.Actor.OnEventDoAction(typeof<PingEvent>, "HandlePing")>] // Error: The type 'OnEventDoActionAttribute' is not accessible from this code location
[<OnEventDoAction(typeof<PingEvent>, "HandlePing")>] // Error: The type 'OnEventDoAction' is not defined
type Server() =
    inherit Actor()

    member this.HandlePing(e : Event) =
        let ping = e :?> PingEvent
        printfn "Server handling ping"
        printfn "Server sending pong back to caller"
        this.SendEvent(ping.Caller, new PongEvent());

// both attribute spec fail
//[<Microsoft.Coyote.Actors.Actor.OnEventDoAction(typeof<PongEvent>, "HandlePong")>] // Error: The type 'OnEventDoActionAttribute' is not accessible from this code location
[<OnEventDoAction(typeof<PongEvent>, "HandlePong")>] // Error: The type 'OnEventDoAction' is not defined
type Client() =

    inherit Actor()

    let mutable serverId : ActorId = null

    override this.OnInitializeAsync(initialEvent : Event) : System.Threading.Tasks.Task =
        printfn "%A initializing" this.Id
        serverId <- (initialEvent :?> SetupEvent).ServerId
        printfn "%A sending ping event to server" this.Id
        this.SendEvent(serverId, new PingEvent(this.Id))
        base.OnInitializeAsync(initialEvent)

    member this.HandlePong() =
        printfn "%A received pong event" this.Id

[<Test>]
let Execute (runtime : IActorRuntime) =
    let serverId = runtime.CreateActor(typeof<Server>)
    runtime.CreateActor(typeof<Client>, new SetupEvent(serverId)) |> ignore
    runtime.CreateActor(typeof<Client>, new SetupEvent(serverId)) |> ignore
    runtime.CreateActor(typeof<Client>, new SetupEvent(serverId)) |> ignore

let runtime = RuntimeFactory.Create()
Execute(runtime) |> ignore
Console.ReadLine() |> ignore

不知道该怎么做才能解决这个问题。

LINQPad文档URI可以直接试用代码。http:/share.linqpad.neta9rif7.linq。

c# f# actor coyote
1个回答
3
投票

不幸的是,他们 宣称 的属性。protected sealed 嵌套 Actor. 虽然F#不能声明任何东西为 protected,它可以遵循访问限制--通常人们执行访问限制是有原因的。

另一种方法是,你可以有一个顶级类,它继承于 Actor 并将客户端实现为嵌套类。但是F#也不支持嵌套类。

我看不出有什么特别的理由要声明为 protected 除了范围污染之外。

可能分叉和改变访问修饰符是目前最简单的选择。


4
投票

是的,这是为了减少作用域污染,并确保你只有在Visual Studio内部有效的地方使用这些类型时才会得到intellisense。 不过建立一个F#例子的想法很酷......

© www.soinside.com 2019 - 2024. All rights reserved.