سؤال

هل هناك أي طريقة للإشارة إلى إعادة التجديف إلى أن المرجع الفارغ لن يحدث بسبب التصميم حسب العقد يتطلب التحقق؟ على سبيل المثال، سيقوم التعليمة البرمجية التالية برفع التحذير (Possible 'null' assignment to entity marked with 'NotNull' attribute) في إعادة عرض على خطوط 7 و 8:

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 يذهب بعيدا.

تحديث

لقد وجدت الحل من خلال التعليم الإلكتروني الذي ذكره مايك أيضا. إليك مثال على كيفية القيام بذلك للحصول على وظيفة في Microsoft.Contracts:

  • إنشاء دليل يسمى 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، والرسالة تختفي!
هل كانت مفيدة؟

المحلول

ملحوظة: اعتبارا من EAP الحالي R # 8.0، يتم تضمين هذه الوظيفة.


إليك حل إصدار Code الحالي (IE .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>

نصائح أخرى

أود أن أضيف ذلك للأشخاص الذين يكتبون أساليب التأكيد الخاصة بهم، ويمكنك تضمين هذه السمات دون ملف 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)
    {
        ...
    }
...
}

الآن أي مكالمة إلى Require.That(a != null) سوف تشير إلى إعادة التجسيد التي لا يمكنك تجاوز هذا الخط إذا a باطل. على عكس تقنية الإرهابيين، سيعمل ذلك على أي شخص باستخدام أساليبك، دون أي عمل إضافي من جانبه.

تحديث

قام Resharper بتغيير نموذج التعليق التوضيحي للعقد اعتبارا من الإصدار 7. إليك الطريقة التي تبدو بها الطريقة المذكورة أعلاه الآن:

public class Require
{
    [ContractAnnotation("requiredCondition:false => halt")]
    public static void That(
        bool requiredCondition,
        string message = null)
    {
        ...
    }
...
}

أعتقد أنك تستطيع ولكنها ليست تافهة. إلقاء نظرة على Resharper مساعدة عبر الإنترنت للحصول على رمز التعليق

وتفهموا فصول BCL والإطار النيوني (وأكثر) لتعزيز قدرات فحص رمز التشكيل.

على سبيل المثال، يؤكد NUNIT أنها مشروحة مع AssertionMethodatttribute. يخبر هذا بإجراء فحص رمز التشهير أنه إذا حصلت على تأكيد assert.isnotnull (FOO)؛ ثم يجب ألا تكون FOO NULL ولن تنتج المهمة "الممكنة" ... "تحذير بعد الآن.

يمكنك إنتاج ملف XML الذي يقوم بإشراف العقود. طرق الإبلاغ للإشارة إلى أنه مثل تأكيد.

السبب في الخروج من الرسالة عند إزالة التأكيد هو أن R # يعمل في وضع "متفائل" افتراضيا. يفترض أن كل شيء غير فارغ حتى تفعل شيئا يشير إلى أنه قد يكون فعليا فارغا. هذا ما يحدث عند إضافة المكالمة إلى String.IsNullOrEmpty. وبعد أنت تفيد بأن s يمكن أن تكون في الواقع فارغة. انها فقط ليست مدركة أن Contract.Requires سوف تتوقف الطريقة عن التنفيذ إذا كان هذا هو الحال، ولكن قمت بحلها مع التوضيحية.

في R # 5.0 يمكنك التغيير إلى وضع متشائم يفترض الأسوأ في كل زاوية.

أخذت Porges 'XML وأضاف التعليقات التوضيحية لتأكيد الأساليب. سوف 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>

غيرت RESHRAPER طراز التعليقات التوضيحية للعقد اعتبارا من الإصدار 7.

تحتاج إلى ملف مختلف. الموقع الجديد (أعتقد فقط من أجل تطبيقات المترو) هو: "C: برامج الملفات (x86) jetbrains resharper v7.1 bin elembernatations .netcore system.diagnostics.contacts contracts.xml"

أنا أستخدم Visual Studio 2012 و .NET 4.5 و Resharper 7.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>

TL؛ DR - إضافة رمز الترجمة الشرطية CONTRACTS_FULL لمشروعك.

ال Contract.Requires(...) الطريقة فارغة وتعطيل، إلا إذا قمت بتمكين واستخدام ملف جهات اتصال الرمز. عن طريق تشغيل إعادة الاتصال يدويا، أو (عادة) تمكينه من خلال خصائص مشروع Visual Studio، وسوف تبقي Contract.Requires(...) رمز في الثنائيات المجمعة وإعادة كتابتها. أنت تعرف أن الكود سيعمل، وتجاهل تحذير RESHHARPER، يمكنك تشغيله واختباره.

ما هي المشكلة إذن؟ لا يعرف إعادة التجسيد أن عقود التعليمات البرمجية قيد التشغيل، لأنها يتم حقنها فقط في وقت تجميع (بعد). في عيون التجديد، يتم تعطيلها بنفس الطريقة DEBUG يعمل رمز Preprocessor وكيفية Visual Studio Grazs مناطق التعليمات البرمجية التي لن تكون جزءا من الثنائيات المجمعة.

#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 يحتاج إلى تعيين قبل تجميعها معها. يتم تنفيذ طرق العقود فعليا مع [ConditionalAttribute("CONTRACTS_FULL")] ويتم تجاهله (غير مدرج في وقت الترجمة) ما لم يتم تعيين العلم. Resharper يحترم هذا العلم، وفترض أن الوظيفة لن تعمل ما لم يتم تعيينها.

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

الحل: إضافة رمز الترجمة الشرطية CONTRACTS_FULL لمشروعك. يرى باستخدام Code Contents Visual Studio ومع RESHHARPER بواسطة هينينج كريوس.


(مصدر: infinitec.de.)

تم إخطار فريق Resharper؛ لا يعتبر تحليل التعليمات البرمجية الإعدادات في علامة التبويب خصائص مشروع "Code Code Contents", دعم عقود كود Microsoft.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top