【问题标题】:How do you assert in algorithimic code in .NET?您如何在 .NET 的算法代码中断言?
【发布时间】:2011-05-12 11:18:37
【问题描述】:

我目前正在为一个大学项目使用 C# 开发一个小型 AI 框架(遗传算法/神经网络)。

我首先关心的是开发一个可重用的框架,所以我将所有东西都设计成非常模块化的。我知道我为此付出了代价(性能),但我觉得我得到的比失去的要多(最好让代码慢一倍而不是失去两倍的时间,然后试图找到不可能发现错误并浪费大量时间尝试添加难以在单一代码块中引入的新内容)。

基本上,我想对我的代码的不同部分、断言进行大量检查。检查运行方法 XI 时是否确实处于正确状态等。这些断言在开发时很有用,但我希望它们远离发布代码(也就是说,当我决定要离开时)为了得到我的最终研究结果而工作了一夜。

我可以看到几种方法来实现这一点:

  1. System.Diagonists.Assert 系列方法。
  2. 代码合同
  3. 拥有 if (x) 然后抛出 InvalidStateException() 被 #if DEBUG / #endif 包围

你会怎么做?为什么?

我也知道单元测试(我正在使用它们),但我也想对代码进行某种断言。

【问题讨论】:

    标签: c# .net algorithm oop code-contracts


    【解决方案1】:

    你可以使用这样的静态方法:

    [Conditional("DEBUG")]
    public static void Assert(bool condition, string message)
    {
        if (!condition)
            throw new InvalidStateException("Assertion failed: " + message);
    }
    

    像这样断言,假设方法定义在一个名为Util的类中:

    Util.Assert(a == b, "a == b");
    

    只有在设置了 DEBUG 符号时,编译器才会发出对该方法的调用,这要归功于 ConditionalAttribute。因此,您无需将此类调用包装在任何 #if 指令中。这将减少代码混乱。

    (请注意,方法本身仍然会被编译。这允许您在不同的程序集中使用这些方法!)

    【讨论】:

    • 代码合同不是以类似的方式工作吗?我的想法是,您可以在发布模式或类似的模式下完全关闭它们。
    • 也许吧。老实说,我不熟悉它。我的答案中的技术是我使用的技术,所以我想我会分享它。我不能说它比代码合同更好还是更差。
    • 我会同意 cdhowie 所说的。代码合同提供了更多,但可能不是您所需要的。所以我认为正确的工具是使用用 Conditional 属性修饰的方法,而不是使用内联的 #if、#else 或 Debug.Asset() 使你的代码内联混乱。
    【解决方案2】:

    #if/#endif 的优势在于,不仅消除了对 assert 函数的调用,而且还消除了所有准备其参数的工作(希望不会产生副作用......)。

    【讨论】:

    • [Conditional(...)]相同。
    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 2011-05-31
    • 2023-03-19
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多