有没有办法让 Resharper 像对待 Debug.Assert 一样对待 Trace.Assert?

Is there any way to make Resharper treat Trace.Assert like Debug.Assert?

它理解如果断言为假 Debug.Assert 将抛出而不是继续,因此它知道断言在那个点之后是真的。

我想对 Trace.Assert 进行同样的推理。是的,你可以继续,如果你继续通过这样的警告然后抛出一个 null 那是你的问题。我想摆脱那些虚假的可能的空引用消息。

这适用于 ReSharper 9.2。

如果您的 ReSharper 版本在 Trace.Assert 上没有注释:

Trace.Assert 方法需要以下 annotation attribute

[ContractAnnotation("condition:false=>halt")]

这告诉 ReSharper,如果 condition 参数是 false,该方法将不会正常 return (halt)。

好吧,如果您是该方法的作者,这就是您在自己的代码中输入的内容。但是您不能只向 System.dll.

插入一个属性

不过您可以使用 external annotations。有了这些,你就得写一些 XML:

<assembly name="System">
  <member name="M:System.Diagnostics.Trace.Assert(System.Boolean)">
    <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
    <attribute ctor="M:JetBrains.Annotations.ContractAnnotationAttribute.#ctor(System.String)">
        <argument>condition:false=&gt;halt</argument>
    </attribute>
  </member>
  <member name="M:System.Diagnostics.Trace.Assert(System.Boolean,System.String)">
    <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
    <attribute ctor="M:JetBrains.Annotations.ContractAnnotationAttribute.#ctor(System.String)">
        <argument>condition:false=&gt;halt</argument>
    </attribute>
  </member>
  <member name="M:System.Diagnostics.Trace.Assert(System.Boolean,System.String,System.String)">
    <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
    <attribute ctor="M:JetBrains.Annotations.ContractAnnotationAttribute.#ctor(System.String)">
        <argument>condition:false=&gt;halt</argument>
    </attribute>
  </member>
</assembly>

我链接到的 help page 解释了如何将其安装到 ReSharper。

或者...您可以在自己的助手 class 中编写自己的 Assert 方法,它只委托给 Trace.Assert,因此您可以使用属性:

[ContractAnnotation("condition:false=>halt")]
public static void Assert(bool condition)
{
    Trace.Assert(condition);
}

我刚刚使用以下示例代码在 ReSharper 9.1.3 中对此进行了测试。

private void M(string a)
{
    Trace.Assert(a != null); // or Debug.Assert(a != null);

    if (a == null)
        Console.WriteLine("a is null");
}

R# 为 Debug.Assert()Trace.Assert() 报告 Console.WriteLine() 调用是 "heuristically unreachable"。之所以如此,是因为这两种方法都在 ReSharper 的 external annotations 中用 [ContractAnnotation("condition:false=>halt")] 注释(您可以通过在方法上按 Ctrl+Shift+F1 并单击“[...]”来查看)。

你有哪个版本的ReSharper/of外部注释包?

顺便说一句:condition:false=>halt 注释并不是真正正确,因为 a) 您可以单击 DefaultTraceListener 消息框中的 "Ignore" 并继续执行,并且 b) 它取决于 Trace.Listeners 配置(例如,如果您调用 Trace.Listeners.Clear() 或将 AssertUiEnabled 属性 设置为 false,消息框甚至不会出现)。