রিশ্যার কৌতূহল: "পরামিতি কেবল পূর্বশর্ত চেক (গুলি) এর জন্য ব্যবহৃত হয়।"


104

কেন রিশার্পার এই কোডটির জন্য আমাকে বিচার করছেন?

    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);
        }
    }

দ্বিতীয় পদ্ধতি ভ্যালিডেটপ্রেসিংভালিউটিটাইপের "সেটিংওয়ালু" প্যারামিটারটি রিশার্পার দ্বারা নিম্নলিখিত বার্তার সাথে ধূসর করা হয়েছে: "পরামিতি 'সেটিংওয়ালু' কেবল পূর্বশর্ত চেক (গুলি) এর জন্য ব্যবহৃত হয়।"


আপনি ঘোষণাপত্র এবং অ্যাসাইনমেন্টটি exceptionMessageif
-ব্লকের

আপনি পদ্ধতিতে এটি করতেও পারেন: প্রত্যাশিত পাঠ + = ""; এবং আপনি পদ্ধতিতে এটি ব্যবহার করার পরে এটি অভিযোগ করা বন্ধ করে দেয়।
পিএইচপিগুরু

উত্তর:


106

এটি বিচার করছে না, এটি সাহায্য করার চেষ্টা করছে :)

যদি রিশার্পার দেখেন যে প্যারামিটারটি কেবলমাত্র ব্যতিক্রম ছুঁড়ে ফেলার জন্য চেক হিসাবে ব্যবহৃত হয়, তবে এটি এটি ধূসর করে দেয় যা ইঙ্গিত করে যে আপনি এটি "বাস্তব" কাজের জন্য আসলে ব্যবহার করছেন না। এটি সম্ভবত একটি ভুল - আপনি যে প্যারামিটারটি ব্যবহার করছেন না কেন তা পাস করবেন? এটি সাধারণত ইঙ্গিত করে যে আপনি এটি প্রাক-শর্তে ব্যবহার করেছেন, তবে তারপরে কোডের অন্য কোনও জায়গায় এটি ব্যবহার করতে ভুলে গেছেন (বা আর প্রয়োজন নেই)।

যেহেতু পদ্ধতিটি একটি ValidateCorrespondingValueTypeদৃser়বিজ্ঞানের পদ্ধতি (এটি যা যা করা হয় সবগুলিই এটির বৈধতা রয়েছে), আপনি পুনঃশিকারের টীকা বিশিষ্টতাগুলি বিশেষত বৈশিষ্ট্যটি ব্যবহার করে একটি বার্তা পদ্ধতি হিসাবে চিহ্নিত করে বার্তাটি দমন করতে পারেন [AssertionMethod]:

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

4
এটি একটি দুর্দান্ত চেক, তবে এই ক্ষেত্রে আর # কিছুটা অতিক্রম করেছে, আপনি কি বলবেন না? settingValueএর ধরণের চেকটি পূর্ব- শর্ত হিসাবে সম্ভব নয় , যেহেতু যে জিনিসটির বিরুদ্ধে এটি যাচাই করা হচ্ছে তা পদ্ধতিটির শরীরে কিছু কাজ না হওয়া পর্যন্ত জানা যায়নি!
আকাশম

6
এজন্য আপনাকে রিসার্পারকে বলা দরকার এটি একটি দৃser়পদ পদ্ধতি। এই পদ্ধতির একমাত্র বিষয় হ'ল অন্য পদ্ধতির প্রাক-শর্ত পরীক্ষা করা। এটি দৃ as় বিশ্বাস, তবে রিশার্পার এটি না জানলে এটি জানতে পারে না [AssertionMethod]
নাগরিকত্ব

10
আমি সবেমাত্র পরিদর্শন তীব্রতাটিকে "দেখায় না" তে পরিবর্তন করেছি, এটি অন্য একটি বিকল্প।
রেগেগুইটার

62
এটি একটি দরকারী বৈশিষ্ট্য হতে পারে, যদি কেউ নিয়মিত অব্যবহৃত প্যারামিটার পরিদর্শন থেকে স্বাধীনভাবে 'প্রাক-শর্ত শুধুমাত্র' পরিদর্শন অক্ষম করতে পারে; যেহেতু এটি দাঁড়িয়ে আছে তদন্তটি বিভিন্ন তীব্রতার দুটি বিষয়কে মেশায় এবং সাধারণত কিছু পরিস্থিতিতে এই কার্যকারিতাটি অকেজো করে তোলে। আমি কোনও উত্স কোড বিশ্লেষণ সরঞ্জামকে খুশি রাখতে কোডটিতে মন্তব্য বা বৈশিষ্ট্য যুক্ত করার ধারণা সম্পর্কেও খুব সংশয়ী, সুতরাং এই মুহুর্তে আমি মনে করি না যে সমস্যার একটি সন্তোষজনক সমাধান রয়েছে।
সার্জ বেলভ

7
এটি সাহায্যের চেষ্টা করা হতে পারে তবে এটি খুব আগ্রাসী। এখন, আপনি যদি মানটি যাচাই করেন এবং তারপর এটি কখনই ব্যবহার না করেন, ঠিক আছে, সম্ভবত এটি ত্রুটি। যাইহোক, এটি আমার একসাথে হাঁপান যেখানে আমি কেবল ত্রুটিতে মানটি ব্যবহার করি। কীভাবে তা উদ্দেশ্যমূলক ছাড়া আর কিছু হতে পারে?
লরেন পেচটেল

21

মজার বিষয় হল, আপনি nameofযদি সি # 6 তে নতুন কার্যকারিতাটি ব্যবহার করেন তবে রিশার্পার ব্যাকআপ করেছে :

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

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

4
এই উত্তরটি আমার পক্ষে উপযুক্ত, এটি একটি ন্যুগেট প্যাকেজ যুক্ত করার চেয়ে কম অনুপ্রবেশজনক
ড্যানিয়েলভি

8

নিম্নলিখিতটি সমস্যার সমাধান করে (রিসার্পার 2016.1.1, ভিএস2015 এ), তবে আমি নিশ্চিত নই যে এটি 'ডান' সমস্যাটি সমাধান করে। যাই হোক না কেন, এটি এই বিষয় সম্পর্কিত রিসার্পার মেকানিক্সে অস্পষ্টতা দেখায়:

এটি সতর্কবার্তা দেয়:

    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();
    }

এটি আকর্ষণীয় যে সমতুল্য কোড (বিপর্যয়টি রিসার্পার দ্বারা করা হয়েছিল: ডি) বিভিন্ন ফলাফল দেয়। দেখে মনে হচ্ছে যে প্যাটার্নের মিলটি কেবল দ্বিতীয় সংস্করণটি গ্রহণ করে না।


6

এই সমস্যার আমার পছন্দের সমাধান করা resharper মনে প্যারামিটার হয় ব্যবহার করা হয়েছে। এই যেমন একটি বৈশিষ্ট্য ব্যবহার উপর একটি সুবিধা আছে UsedImplicitlyকারন যদি কখনও আপনি কি স্টপ যে পরামিতি ব্যবহার করে, resharper আপনি আবার সাবধান শুরু হবে। আপনি যদি কোনও বৈশিষ্ট্য ব্যবহার করেন তবে পুনঃভাগটি ভবিষ্যতের প্রকৃত সতর্কতাগুলিও ধরবে না।

প্যারামিটারটি ব্যবহার করা হয়েছে বলে মনে করে পুনরায় ভাগ করার সহজ উপায় হ'ল throwকোনও পদ্ধতির পরিবর্তে । এর পরিবর্তে ...

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

...তুমি লেখ:

if(myPreconditionParam == wrong)
    new Exception(...).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]যেমন ব্যবহার করি নি তেমন ব্যবহার করতে চাই নি, এবং স্পষ্টভাবে ব্যবহৃত এটি আমার ক্ষেত্রে এটি আরও নির্ভুল বলে মনে হচ্ছে (আমি কোনও কনস্ট্রাক্টরের কলব্যাকের মান দিয়ে যাচ্ছিলাম এবং নির্মিত বস্তুটি ফিরিয়ে দিচ্ছিলাম)।
মিঃলরে

2

অন্যরা ইতিমধ্যে প্রশ্নের উত্তর দিয়েছেন, কিন্তু সতর্কতাটি বন্ধ করার নিম্নলিখিত উপায়গুলির কথা কেউ উল্লেখ করেনি।

কেবলমাত্র সেই পদ্ধতির জন্য এটিকে বন্ধ করতে পদ্ধতির স্বাক্ষরের উপরে এটি যুক্ত করুন:

    // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local

এটি পুরো ফাইলটির জন্য বন্ধ করার জন্য শ্রেণীর ঘোষণার উপরে এটি যুক্ত করুন:

     // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local

4
একটি অসুবিধা হ'ল আপনি যে ডাইন প্যারামিটারটি বোঝাতে চেয়েছেন তা নির্দিষ্ট করতে পারবেন না।
আসুন

4
@comecme আপনি নির্দিষ্ট প্যারামিটারের চারপাশে মন্তব্যগুলি অক্ষম এবং পুনরুদ্ধার করে একটি একক প্যারামিটারের জন্য অক্ষম করতে পারেন । আমি সেই ক্ষেত্রে প্রতিটি পরামিতিটিকে তার নিজস্ব লাইনে রাখার পরামর্শ দেব; এখনও কুরুচিপূর্ণ কিন্তু কম তাই (আমার মতে)
ট্র্যাভিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.