我遇到了一些看起来像这样的代码。
member this.Send (data:array<byte>) =
if tcpClient.Connected then
// Send something.
member this.Open () =
if not tcpClient.Connected then
// Connect.
这是一个潜在的错误hive,不断检查是否在执行操作之前查看TcpClient
是否已连接。
类似的问题是在执行该操作之前检查某物是否是null
。
处理此问题的一般方法是什么?我正在思考一个单调的单调,该单调抽象这一无聊的办理登机手续。
编辑:
可能我可以编写许多方法,每个方法都必须检查我们是否已连接。
member this.SendName name =
if tcpClient.Connected then
// Send name
member this.ThrottleConnection percent =
if tcpClient.Connected then
// Throttle
member this.SendAsTest text =
if tcpClient.Connected then
// Send as text.
因此,这取决于您是要在包装器类中还是外部进行检查。在班上进行检查,我看不出计算表达式如何真正相关;您不是约束操作。
仅当您在包装程序类之外进行检查(即来自调用功能)时,工作流的表达式才会有用。如果将connected
构建器一起创建,则结果代码看起来像
connected {
do! wrapper.Send(..)
do! wrapper.Throttle(..)
do! wrapper.SendAsTest(..)
}
但是,这实际上并不比
简单if wrapper.connected do
wrapper.Send(..)
wrapper.Throttle(..)
wrapper.SendAsTest(..)
那么,有点,有什么意义,对
如果您有多个tcpClient
包装对象,并且需要它们在工作流程中连接,这将是更有意义的。这就是" monadic"方法的目的。
connected {
do! wrapper1.Send(..)
do! wrapper2.Throttle(..)
do! wrapper3.SendAsText(..)
}
但是,特定于您在包装班中进行检查的示例,就像我之前说的那样,单调不适用。解决该特定问题的一种整洁方法是尝试模仿一些前提条件,例如以下链接http://laurent.le-brun.eu/site/site/index.php/2008/03/03/26/26/32-design-32-design-by-contract---与fsharp。我不知道它是否比if
语句更直观,但是如果您正在寻找一种有趣的事情来做事的方式,那是我能想到的最好的。
最终您的现有代码与其所获得的紧凑。大概不是您功能的所有都将从相同的if
语句开始,因此那里没有任何不必要的重复性。