首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在F#代码保护的父类型嵌套属性类型中使用Microsoft Coyote

如何在F#代码保护的父类型嵌套属性类型中使用Microsoft Coyote
EN

Stack Overflow用户
提问于 2020-05-09 08:47:16
回答 2查看 142关注 0票数 3

在这里,F#和C#之间是否存在语言差异,从而阻碍了F#代码对Microsoft的使用?

因为OnEventDoActionAttribute是用受保护的访问修饰符在继承类型Microsoft.Coyote.Actors.Actor中定义的,所以在C#中继承的参与者类型中仍然可以访问它,而在F#中则不是这样。

Hello示例转换为F#:

代码语言:javascript
复制
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.net/a9rif7.linq

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-09 18:42:56

不幸的是,它们将属性已声明为嵌套在Actor中的protected sealed。虽然F#不能将任何内容声明为protected,但它可以遵循访问限制--通常人们强制执行访问限制是有原因的。

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

除了范围污染之外,我不认为它被宣布为protected有什么特别的原因。

现在,分叉和更改访问修饰符可能是最简单的选择。

票数 3
EN

Stack Overflow用户

发布于 2020-05-09 22:10:55

是的,这是为了减少范围污染,并确保在Visual中使用这些类型的有效位置时才能获得这些类型的intellisense。构建一个F#示例的好主意.

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61694051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档