在C#中,如何将某些方法调用完全保留在代码库之外?

我试图摆脱所有DateTime.Now方法调用,并用我自己的GetNow()方法替换它们,有时可能会返回固定日期以进行测试。

如何强制执行以后没有人添加DateTime.Now调用? 我可以使用NDependStyleCop在我的持续集成服务器上进行检查吗?

使用NDepend, 编写此规则非常容易:

 // Forbid DateTime.Now, use xxx.GetNow() instead WARN IF Count > 0 IN SELECT METHODS WHERE IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()" 

注意:

  • WARN IF Count> 0 IN的前缀可将CQL查询转换为规则
  • 通过字符串System.DateTime.get_Now()引用属性的方式
  • 前缀OPTIONAL表示“如果找不到属性get_Now,则不发出编译错误”。 这是有道理的,因为如果您的代码不再使用get_Now(),则不再从NDepend分析中引用它。

另外,要生成原始查询…

 SELECT METHODS WHERE IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()" 

…只需右键单击DateTime.get_Now()并选择直接使用我的选择方法….

在此处输入图像描述

首先, DateTime.Now是一个属性
这意味着您不需要在调用后放置括号。

其次,如果出于测试目的,您指的是像NUnit这样的框架,您可能需要查看Microsoft Moles ,它允许您在测试时用自己的自定义实现替换任何静态方法调用 。 哎呀,很酷:

 [Test] [ExpectedException (typeof (Y2KBugException))] public void TestY2KBug () { MDateTime.NowGet = () => new DateTime (2001, 1, 1); Bomb.DetonateIfY2K (); } public static class Bomb { public static void DetonateIfY2K () { if (DateTime.Now == new DateTime (2001, 1, 1)) throw new Y2KBugException (); // take cover! } } 

没有真正的方法来强制执行这样的事情。

你最接近的是制作一个自定义的FxCop规则或自定义的Visual Studio代码分析规则来对DateTime.Now的调用进行错误/警告。

您可以在测试中使用Moles在需要时提供您自己的DateTime.Now,而无需修改任何调用它的现有代码。

另一种选择可能是在编译后修改程序集以调用其他内容。 (也许,使用Mono.Cecil重写IL,并在VS中的后期构建中添加一个命令来运行它。)

您也许可以获取Mono源并自行构建一个自定义的mscorlib,并删除该function。

一种方法可能是在您选择的源控件存储库中添加预提交挂钩,以查找DateTime.Now并在您找到有问题的字符串时中止签入。 它不是万无一失的,它可能会让你的同事烦恼,但它应该有助于它远离代码库。

我不认为这是可能的。 您实际上要做的是覆盖DateTime的结构function。

我能想到的唯一方法就是使用自定义类来包装DateTime的常用function并根据需要提供不同的function……