如何处理在每个方法调用中检查有效状态
How to deal with checking for valid state in every method call
我遇到过类似这样的代码。
member this.Send (data:array<byte>) =
if tcpClient.Connected then
// Send something.
member this.Open () =
if not tcpClient.Connected then
// Connect.
这是一个潜在的错误配置单元,在对其执行操作之前不断检查 TcpClient
是否已连接。
一个类似的问题是在对某个东西执行操作之前检查它是否 null
。
处理此问题的一般方法是什么?
我在想一个 monad 的思路,它抽象了这个无聊的检查。
编辑:
可能我可以编写许多方法,每个方法都必须检查我们是否已连接。
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.
因此,这取决于您是要在包装器内部还是外部进行检查 class。在 class 中进行检查,我看不出计算表达式是如何真正相关的;你没有绑定操作。
工作流表达式只有在您在包装器外部进行检查时才有用 class(即从调用函数)。如果您一起创建一个 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(..)
}
但是,具体到您在包装器内部进行检查的示例 class,正如我之前所说,monad 将不适用。解决该特定问题的一种巧妙方法是尝试模仿一些先决条件,例如以下 link http://laurent.le-brun.eu/site/index.php/2008/03/26/32-design-by-contract-with-fsharp。我不知道它是否比 if
语句更直观,但如果您正在寻找一种有趣的 fsharp-y 方式来做事,那是我能想到的最好的方法。
最终,您现有的代码将尽可能紧凑。大概不是 所有 的函数都以相同的 if
语句开头,所以那里没有不必要的重复。
我遇到过类似这样的代码。
member this.Send (data:array<byte>) =
if tcpClient.Connected then
// Send something.
member this.Open () =
if not tcpClient.Connected then
// Connect.
这是一个潜在的错误配置单元,在对其执行操作之前不断检查 TcpClient
是否已连接。
一个类似的问题是在对某个东西执行操作之前检查它是否 null
。
处理此问题的一般方法是什么? 我在想一个 monad 的思路,它抽象了这个无聊的检查。
编辑:
可能我可以编写许多方法,每个方法都必须检查我们是否已连接。
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.
因此,这取决于您是要在包装器内部还是外部进行检查 class。在 class 中进行检查,我看不出计算表达式是如何真正相关的;你没有绑定操作。
工作流表达式只有在您在包装器外部进行检查时才有用 class(即从调用函数)。如果您一起创建一个 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(..)
}
但是,具体到您在包装器内部进行检查的示例 class,正如我之前所说,monad 将不适用。解决该特定问题的一种巧妙方法是尝试模仿一些先决条件,例如以下 link http://laurent.le-brun.eu/site/index.php/2008/03/26/32-design-by-contract-with-fsharp。我不知道它是否比 if
语句更直观,但如果您正在寻找一种有趣的 fsharp-y 方式来做事,那是我能想到的最好的方法。
最终,您现有的代码将尽可能紧凑。大概不是 所有 的函数都以相同的 if
语句开头,所以那里没有不必要的重复。