रिस्पेरस क्यूरोसिटी: "पैरामीटर का उपयोग केवल पूर्व-भुगतान जांच (एस) के लिए किया जाता है।"


102

क्यों ReSharper मुझे इस कोड के लिए न्याय कर रहा है?

    private Control GetCorrespondingInputControl(SupportedType supportedType, object settingValue)
    {
        this.ValidateCorrespondingValueType(supportedType, settingValue);

        switch(supportedType)
        {
            case SupportedType.String:
                return new TextBox { Text = (string)settingValue };
            case SupportedType.DateTime:
                return new MonthPicker { Value = (DateTime)settingValue, ShowUpDown = true };
            default:
                throw new ArgumentOutOfRangeException(string.Format("The supported type value, {0} has no corresponding user control defined.", supportedType));
        }
    }

    private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
    {
        Type type;

        switch(supportedType)
        {
            case SupportedType.String:
                type = typeof(string);
                break;
            case SupportedType.DateTime:
                type = typeof(DateTime);
                break;
            default:
                throw new ArgumentOutOfRangeException(string.Format("The supported type value, {0} has no corresponding Type defined.", supportedType));
        }
        string exceptionMessage = string.Format("The specified setting value is not assignable to the supported type, [{0}].", supportedType);
        if(settingValue.GetType() != type)
        {
            throw new InvalidOperationException(exceptionMessage);
        }
    }

दूसरी विधि ValidateCorrespeasingValueType के "सेटिंगवैल्यू" पैरामीटर को ReSharper द्वारा निम्न संदेश के साथ धूसर किया जाता है: "पैरामीटर 'सेटिंगवैल्यू' का उपयोग केवल पूर्व-भुगतान जांच (एस) के लिए किया जाता है।"


आप घोषणा और का काम ले जा सकते हैं exceptionMessageमें if-block :)
AakashM

आप इस विधि में भी कर सकते हैं: अपेक्षित + + ""; और यह शिकायत करना बंद कर देता है क्योंकि आपने इसे विधि में इस्तेमाल किया है।
PHPGuru

जवाबों:


104

यह न्याय नहीं कर रहा है, यह मदद करने की कोशिश कर रहा है :)

यदि ReSharper देखता है कि एक पैरामीटर का उपयोग केवल एक अपवाद को फेंकने के लिए चेक के रूप में किया जाता है, तो यह इसे बाहर निकालता है, यह दर्शाता है कि आप वास्तव में "वास्तविक" कार्य के लिए इसका उपयोग नहीं कर रहे हैं। यह सबसे अधिक गलती की संभावना है - आप जिस पैरामीटर का उपयोग करने वाले नहीं हैं, उसमें पास क्यों करें? यह आमतौर पर इंगित करता है कि आपने इसे पूर्व-स्थिति में उपयोग किया है, लेकिन फिर कोड में कहीं और इसका उपयोग करने के लिए भूल गए (या अब आवश्यकता नहीं है)।

चूँकि विधि एक अभिकथन विधि है (अर्थात, यह जो करता है वह मान्य है), आप ValidateCorrespondingValueTypeReSharper के एनोटेशन विशेषताओं , विशेष रूप से [AssertionMethod]विशेषता का उपयोग करके, संदेश को एक अभिकथन विधि के रूप में चिह्नित कर सकते हैं।

[AssertionMethod]
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
  // …
}

3
यह एक अच्छा चेक है, लेकिन इस मामले में आर # ओवर-बिट पर पहुंच गया है, क्या आप नहीं कहेंगे? पर जांच settingValueके प्रकार संभव नहीं हो सकता है एक पूर्व शर्त, बात इसके खिलाफ नहीं जाना जाता है जब तक कुछ काम विधि के मुख्य भाग में किया गया है की जाँच की जा रही है के बाद से!
आकाशवाणी

6
इसलिए आपको ReSharper को बताने की जरूरत है कि यह एक जोरदार तरीका है। इस पद्धति का एकमात्र बिंदु किसी अन्य विधि के लिए पूर्व-स्थिति की जांच करना है। यह एक जोर है, लेकिन ReSharper यह नहीं जान सकता कि जब तक आप इसे नहीं बताते [AssertionMethod]
नागरिकता

10
मैंने केवल निरीक्षण गंभीरता को "डू नॉट शो" में बदल दिया, यह एक और विकल्प है।
रेगेगिटेरिटी

61
यह एक उपयोगी विशेषता हो सकती है, अगर कोई नियमित रूप से अप्रयुक्त पैरामीटर निरीक्षण से स्वतंत्र रूप से 'पूर्व शर्त केवल' निरीक्षण को अक्षम कर सकता है; जैसा कि यह निरीक्षण खड़ा करता है अलग गंभीरता के दो मुद्दों को मिलाता है और आम तौर पर कुछ स्थितियों में इस कार्यक्षमता को बेकार कर देता है। मैं कोड को केवल स्रोत स्रोत विश्लेषण टूल को खुश रखने के लिए टिप्पणियों या विशेषताओं को जोड़ने के विचार से बहुत उलझन में हूं, इसलिए फिलहाल मुझे नहीं लगता कि समस्या का कोई संतोषजनक समाधान है।
सर्ज बेलोव

7
यह मदद करने की कोशिश कर रहा हो सकता है लेकिन यह बहुत आक्रामक है। अब, यदि आप मान को सत्यापित करते हैं और फिर इसका उपयोग कभी नहीं करते हैं, तो ठीक है, यह एक त्रुटि है। हालाँकि, यह मुझ पर एक से अधिक की मैपिंग है जहाँ मैं केवल त्रुटि में मूल्य का उपयोग करता हूं। और क्या हो सकता है, लेकिन इरादतन कुछ भी हो सकता है?
लोरेन Pechtel

20

दिलचस्प बात यह है कि यदि आप नए का उपयोग करते हैं तो ReSharper बंद हो जाता है nameof C # 6 में कार्यक्षमता का जाता है:

static void CheckForNullParameters(IExecutor executor, ILogger logger)
{
    if (executor == null)
    {
        throw new ArgumentNullException(nameof(executor));
    }

    if (logger == null)
    {
        throw new ArgumentNullException(nameof(logger));
    }
}

3
यह उत्तर मुझे सूट करता है, यह एक नुगेट पैकेज को जोड़ने की तुलना में कम दखल नहीं है
डैनिल्व

8

निम्नलिखित समस्या को हल करता है (ReSharper 2016.1.1, VS2015 में), लेकिन मुझे यकीन नहीं है कि यह 'सही' समस्या को हल करता है। किसी भी मामले में, यह इस विषय के बारे में ReSharper के यांत्रिकी में अस्पष्टता दिखाता है:

यह चेतावनी देता है:

    private void CheckForNull(object obj)
    {
        if (ReferenceEquals(obj, null))
        {
            throw new Exception();
        }
    }

लेकिन यह नहीं है:

    private void CheckForNull(object obj)
    {
        if (!ReferenceEquals(obj, null))
        {
            return;
        }
        throw new Exception();
    }

यह दिलचस्प है कि समतुल्य कोड (प्रत्यावर्तन ReSharper: D द्वारा किया गया था) अलग-अलग परिणाम देता है। ऐसा लगता है कि केवल मेल खाने वाला पैटर्न दूसरा संस्करण नहीं उठाता है।


6

इस समस्या के लिए मेरा पसंदीदा समाधान है, ऐसा लगता है कि पैरामीटर का उपयोग किया जाता है। यह एक विशेषता का उपयोग करने पर एक फायदा है जैसे UsedImplicitlyकि यदि आप कभी भी करते हैं उस पैरामीटर का उपयोग बंद कर देते हैं, तो पुनर्जीवन आपको फिर से चेतावनी देना शुरू कर देगा। यदि आप एक विशेषता का उपयोग करते हैं, तो रिसर्चर भविष्य की वास्तविक चेतावनियों को पकड़ नहीं पाएंगे।

एक आसान तरीका है कि पुनर्विक्रेता को लगता है कि पैरामीटर का उपयोग throwएक विधि के साथ प्रतिस्थापित करके किया जाता है । इसके बजाय ...

if(myPreconditionParam == wrong)
    throw new Exception(...);

...तुम लिखो:

if(myPreconditionParam == wrong)
    new Exception(...).ThrowPreconditionViolation();

यह भविष्य के प्रोग्रामर के लिए अच्छी तरह से स्व-दस्तावेजीकरण है, और पुनर्विक्रेता रोना छोड़ देता है।

ThrowPreconditionViolation का कार्यान्वयन तुच्छ है:

public static class WorkAroundResharperBugs 
{
    //NOT [Pure] so resharper shuts up; the aim of this method is to make resharper 
    //shut up about "Parameter 'Foobaar' is used only for precondition checks" 
    //optionally: [DebuggerHidden]
    public static void ThrowPreconditionViolation(this Exception e)
    {
        throw e;
    }
}

अपवाद पर एक विस्तार विधि है नाम स्थान प्रदूषण है, लेकिन यह काफी निहित है।


+1 का उल्लेख करने के लिए [UsedImplicitly], मैं [AssertionMethod]इसका उपयोग नहीं करना चाहता था और यह मेरे मामले में अधिक सटीक लगता था (मैं एक निर्माणकर्ता में एक कॉलबैक के लिए एक मूल्य पारित कर रहा था और निर्मित वस्तु को वापस कर रहा था)।
MrLore

1

दूसरों ने पहले ही सवाल का जवाब दे दिया है, लेकिन किसी ने चेतावनी को बंद करने के निम्नलिखित तरीकों का उल्लेख नहीं किया।

इसे केवल उस विधि के लिए बंद करने के लिए विधि हस्ताक्षर के ऊपर जोड़ें:

    // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local

इसे पूरी फ़ाइल के लिए बंद करने के लिए वर्ग घोषणा के ऊपर जोड़ें:

     // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local

एक नुकसान यह है कि आप चुड़ैल पैरामीटर को निर्दिष्ट नहीं कर सकते हैं जिसका मतलब है।
कॉमेकम

1
@comecme आप एकल पैरामीटर के लिए अक्षम कर सकते हैं और उस विशेष पैरामीटर के आसपास टिप्पणियों को अक्षम करके पुनर्स्थापित कर सकते हैं । मैं उस मामले में हर पैरामीटर को अपनी लाइन पर रखने का सुझाव दूंगा; अभी भी बदसूरत लेकिन इतना कम (मेरी राय में)।
ट्रैविस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.