52

契約による設計がチェックを必要とするためにnull参照が発生しないことをReSharperに示す方法はありますか?たとえば、次のコードは、Possible 'null' assignment to entity marked with 'NotNull' attribute7行目と8行目のReSharperで警告()を発生させます。

private Dictionary<string, string> _Lookup = new Dictionary<string, string>();

public void Foo(string s)
{
    Contract.Requires(!String.IsNullOrEmpty(s));

    if (_Lookup.ContainsKey(s))
        _Lookup.Remove(s);
}

本当に奇妙なのは、Contract.Requires(...)行を削除すると、ReSharperメッセージが消えることです。

アップデート

私はExternalAnnotationsを通じて解決策を見つけました。これは、以下のMikeによっても言及されています。これは、Microsoft.Contractsの関数に対してこれを行う方法の例です。

  • ReSharperディレクトリMicrosoft.Contractsの下にというディレクトリを作成します。ExternalAnnotations
  • 次に、というファイルを作成し、次のMicrosoft.Contracts.xmlように入力します。

<assembly name="Microsoft.Contracts">
    <member name="M:System.Diagnostics.Contracts.Contract.Requires(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
</assembly>

  • Visual Studioを再起動すると、メッセージが消えます。
4

7 に答える 7

43

:現在のR#8.0 EAPの時点では、この機能が含まれています。


コードコントラクトの現在の(つまり.NET 4.0)バージョンのソリューションは次のとおりです。

内部...\ExternalAnnotations\mscorlib\Contracts.xmlに、以下を追加します。

<assembly name="mscorlib">
    <member name="M:System.Diagnostics.Contracts.Contract.Assert(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Assert(System.Boolean, System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Assume(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Assume(System.Boolean, System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires``1(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires(System.Boolean,System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires``1(System.Boolean,System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Invariant(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Invariant(System.Boolean,System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
</assembly>
于 2009-11-07T13:47:56.913 に答える
19

独自のアサーションメソッドなどを作成する人のために、外部XMLファイルなしでこれらの属性を含めることができることを追加したいと思います。Visual Studioで、に移動しReSharper > Options > Code AnnotationsてボタンをクリックしCopy default implementation to clipboardます。次に、(ソリューション内の任意の場所に)新しいファイルを作成し、クリップボードからコードを貼り付けます。これで、次のようなメソッドを作成できます。

public class Require
{
    [AssertionMethod]
    public static void That(
        [AssertionCondition(AssertionConditionType.IS_TRUE)] 
        bool requiredCondition,
        string message = null)
    {
        ...
    }
...
}

これで、への呼び出しは、がnullRequire.That(a != null)の場合、この行を通過できないことをReSharperに示します。aExternalAnnotations手法とは異なり、これは、メソッドを使用するすべての人にとって、追加の作業なしで機能します。

アップデート

Resharperは、バージョン7でコントラクトアノテーションモデルを変更しました。上記のメソッドは次のようになります。

public class Require
{
    [ContractAnnotation("requiredCondition:false => halt")]
    public static void That(
        bool requiredCondition,
        string message = null)
    {
        ...
    }
...
}
于 2010-06-11T20:58:38.113 に答える
5

私はあなたができると思いますが、それは些細なことではありません。コードアノテーションについては、Resharperオンラインヘルプをご覧ください

彼らは、BCLクラスとNUnitフレームワーク(およびその他)に注釈を付けて、Resharpersコード検査機能を強化しました。

たとえば、NUnitは、AssertionMethodAttributeで注釈を付けたと主張します。これは、Resharpersのコード検査に、Assert.IsNotNull(foo);を通過した場合に通知します。その場合、fooはnullであってはならず、「Possible'null'assignment...」警告は生成されなくなります。

Contracts.Requiresメソッドに注釈を付けるxmlファイルを作成して、それがAssertのようなものであることを示すことができます。

于 2009-05-30T15:35:12.330 に答える
4

アサーションを削除するとメッセージが消える理由は、R#がデフォルトで「楽観的」モードで動作するためです。実際にnullになる可能性があることを示す何かを行うまで、すべてがnullではないと想定します。に呼び出しを追加すると、これが発生しますString.IsNullOrEmpty。あなたはそれsが実際にはnullである可能性があると述べています。Contract.Requiresその場合、メソッドが実行を停止することはわかりませんが、アノテーションを使用して解決しました。

R#5.0では、隅々で最悪の事態を想定する悲観的なモードに変更できます。

于 2009-12-17T17:24:34.957 に答える
3

PorgesのXMLを使用して、AssertメソッドとAssumeメソッドのアノテーションを追加しました。他の人がメソッドを追加したい場合に備えて、この回答をwikiで確認します。

<assembly name="mscorlib">
    <member name="M:System.Diagnostics.Contracts.Contract.Assert(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Assert(System.Boolean, System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Assume(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Assume(System.Boolean, System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires``1(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires(System.Boolean,System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Requires``1(System.Boolean,System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Invariant(System.Boolean)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
    <member name="M:System.Diagnostics.Contracts.Contract.Invariant(System.Boolean,System.String)">
        <attribute ctor="M:JetBrains.Annotations.AssertionMethodAttribute.#ctor"/>
        <parameter name="condition">
            <attribute ctor="M:JetBrains.Annotations.AssertionConditionAttribute.#ctor(JetBrains.Annotations.AssertionConditionType)">
                <argument>0</argument>
            </attribute>
        </parameter>
    </member>
</assembly>
于 2010-08-25T16:59:11.863 に答える
2

Resharperは、バージョン7から契約アノテーションモデルを変更しました。

別のファイルが必要です。新しい場所(Metroアプリの場合のみ)は次のとおりです: "C:\ Program Files(x86)\ JetBrains \ ReSharper \ v7.1 \ Bin \ ExternalAnnotations \ .NETCore \ System.Diagnostics.Contracts \ Contracts.xml"

VisualStudio2012と.Net4.5およびResharper7.1を使用しています。

コンテンツ:

<assembly name="System.Diagnostics.Contracts">
    <member name="M:System.Diagnostics.Contracts.Contract.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.Contracts.Contract.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.Contracts.Contract.Assume(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.Contracts.Contract.Assume(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.Contracts.Contract.Requires(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.Contracts.Contract.Requires``1(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.Contracts.Contract.Requires(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.Contracts.Contract.Requires``1(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.Contracts.Contract.Invariant(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.Contracts.Contract.Invariant(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>
</assembly>
于 2012-12-17T13:23:15.847 に答える
0

TL;DR-条件付きコンパイルシンボルCONTRACTS_FULLをプロジェクトに追加します。

コード連絡先リライタを有効にして使用しない限り、Contract.Requires(...)メソッドは空で無効になっています。リライターを手動で実行するか、(通常は)Visual Studioプロジェクトのプロパティを使用してリライターを有効にすることContract.Requires(...)で、コンパイルおよびリライトされたバイナリにコードを保持します。コードが機能することはわかっています。Resharperの警告を無視して、コードを実行してテストできます。

では、何が問題なのでしょうか。Resharperは、コードコントラクトが実行されていることを認識していません。これは、コードコントラクトが実際には(ポスト)コンパイル時にのみ注入されるためです。Resharperの目には、プリプロセッサシンボルが機能するのと同じ方法で無効になり、VisualStudioがDEBUGコンパイル済みバイナリの一部ではないコードの領域をグレー表示する方法が無効になります。

#ifdef DEBUG
    Console.WriteLine("I'm in DEBUG mode, so this is probably a Debug build.");
#else
    Console.WriteLine("Let's assume this is a Release build.");
#endif

コードコントラクトのユーザーマニュアル(第2章、最初の段落)およびContractExtensions.cs(コードコントラクトのインストールフォルダに含まれている)のソースコードによると、CONTRACTS_FULLコンパイルする前に設定する必要があります。フラグが設定されていない限り、 Contractメソッドは実際に実装さ[ConditionalAttribute("CONTRACTS_FULL")]、無視されます(コンパイル時には含まれません)。Resharperはこのフラグを尊重し、設定されていない限り関数は実行されないと想定します。

[ConditionalAttribute("CONTRACTS_FULL")]
public static void Requires(bool condition) { ... }

解決策:プロジェクトに条件付きコンパイルシンボルを追加CONTRACTS_FULLします。コードコントラクトの使用VisualStudioおよびHenningKrauseによるResharperを参照してください。


(ソース:infinitec.de

Resharperチームに通知されました。コード分​​析では、[コードコントラクト]プロジェクトのプロパティタブ、 [ Microsoftコードコントラクトのサポート]の設定は考慮されません

于 2012-07-26T01:43:25.180 に答える