【问题标题】:What are guard methods/classes?什么是守卫方法/类?
【发布时间】:2009-10-20 23:45:58
【问题描述】:

我刚刚注意到question 中提到的保护方法/类,我并没有真正从答案中得到这个概念。唉,Jon Skeet 指向 MS 网站的链接从未加载过。一些快速的 Google 搜索似乎只产生产品,而不是软件工程概念。

任何解释和/或示例将不胜感激。 (尤其是 .Net 方面。)

【问题讨论】:

标签: .net class methods guard


【解决方案1】:

Guard 子句是面向方面编程的一部分,您可以在其中定义什么是方法的允许输入。

根据我对 .Net 实现的了解(我还没有真正研究过),您可以使用属性来执行此操作,例如

public static void NeverGetNull([ThisParamNotNull]MyClass i, [ThisParamNotNull]OtherClass j)
{
   // Will never need to check for null values on i or j!
}

我实际上知道 Erlang 中的保护表达式是什么,其中方法调度依赖于保护方法。我将在下面给出一些伪代码来说明这一点:

myMethod(input i) where i is an int
{
 return i + 10
}
myMethod(input i) where i is an int and i > 10
{
 return i - 10
}

var i = myMethod(1) // returns 11
var i = myMethod(i) // returns 1

可能不是很明显,您可以在派发期间评估的守卫中提供一个表达式。很整洁,嘿?

【讨论】:

  • 有趣。当输入不允许时会发生什么?例如在您的伪代码示例中,您从值 -5 开始?
  • 好吧,如果所有的守卫都失败了,那么方法调用就会失败。没有对手。这与您尝试调用在 C# 中没有匹配签名的方法时相同。但在我的例子中,-5 是一个有效的输入,所以首先你会得到 5,然后是 15,第三次调用该方法会得到 5。希望清除它吗?
【解决方案2】:

如果您不指定异常,则 .NET 将抛出 RaiseContractFailedEvent,但您可以指定 ArgumentOutOfRangeExceptionArgumentNullException

如果您查看 Jon Skeet 的链接,在文档 pdf 中您会看到许多示例,其中一个是:

Contract.Requires( x ! = null );

这是合同设计的一部分,您可以在其中指定前置条件和后置条件。好处是在使用入参之前不需要做大量的验证,它可以帮助调用函数知道结果是符合约定的,所以,如果字符串返回是不允许的为 null 则由于前置条件检查,您不必在调用函数时测试 null。

【讨论】:

    【解决方案3】:

    这是对典型保护子句用例的一个很好的概括:

    Refactoring guard clauses, or “How to ask politely”

    【讨论】:

    • 我从链接中查看了那篇文章,老实说,从之后的讨论中,它似乎更像是如何不做保护条款。
    猜你喜欢
    • 2016-04-26
    • 2017-11-27
    • 2022-01-22
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    相关资源
    最近更新 更多