কেন একটি সি সিতে প্রায়শই "নাল! = ভেরিয়েবল" পরিবর্তে "পরিবর্তনশীল! = নাল" দেখেন?


103

সি # তে, আপনি যে শর্তটি শর্তটি বর্ণনা করেছেন তার ক্রম ছাড়ের গতিতে কি কোনও পার্থক্য রয়েছে?

if (null != variable) ...
if (variable != null) ...

সাম্প্রতিককালে, আমি প্রথমটি বেশিরভাগ সময় দেখেছি এবং দ্বিতীয়টির অভ্যস্ত হওয়ার পরে এটি আমার দৃষ্টি আকর্ষণ করেছে।

যদি কোনও পার্থক্য না থাকে তবে প্রথমটির সুবিধা কী?



কিছু প্রোগ্রামিং ল্যাঙ্গুয়েজ যদি কন্ডিশন মান মান শুরু করতে সমর্থন করে। এই জাতীয় ভাষায় যদি আমরা LValue এর সাথে আরভালিউয়ের সাথে তুলনা করতে চাই তবে আক্ষরিক থেকে বাম দিকে যেমন ব্যবহার করা ভাল অনুশীলন হয় (1 == i)। সুতরাং দুর্ঘটনাক্রমে যদি আমরা = বরং == রাখি তবে এটি সংকলক ত্রুটি দেয়।
যুগল পঞ্চাল

উত্তর:


160

এটি সি থেকে একটি হোল্ড-ওভার, যদি আপনি হয় খারাপ সংকলক ব্যবহার করেন বা সতর্কবাণী যথেষ্ট পরিমাণে আপ না হয়ে থাকে তবে এটি কোনও সতর্কতা সহ সংকলন করবে (এবং প্রকৃতপক্ষে আইনী কোড):

// Probably wrong
if (x = 5)

যখন আপনি সম্ভবত সম্ভবত বোঝাতে চেয়েছিলেন

if (x == 5)

আপনি সি এর মাধ্যমে এটিকে ঘিরে কাজ করতে পারেন:

if (5 == x)

এখানে একটি টাইপোর ফলে অবৈধ কোড আসবে।

এখন, সি # তে এটি সমস্ত পিলল। যদি আপনি দুটি বুলিয়ান মানগুলির তুলনা না করেন (যা বিরল, আইএমই) আপনি আরও পঠনযোগ্য কোডটি লিখতে পারেন, "যদি" বিবৃতিতে শুরু করতে বুলিয়ান অভিব্যক্তি প্রয়োজন, এবং " x=5" ধরণটি Int32নয়, তবে নয় Boolean

আমি আপনাকে পরামর্শ দিচ্ছি যদি আপনি এটি আপনার সহকর্মীদের কোডটিতে দেখতে পান তবে আপনি তাদের আধুনিক ভাষার পদ্ধতিতে শিক্ষিত করুন এবং ভবিষ্যতে আরও প্রাকৃতিক রূপ লেখার পরামর্শ দিন।


6
আমার সহকর্মীরা সকলেই আমাকে এটি দিয়ে বাদাম চালায়, এবং কোথাও কোঁকড়ানো বন্ধনী চাইলে এমনকি যদি একটি বিবৃতি দেওয়া হয় ... (যদি আপনি পরে 'বুঝতে না পেরে' কিছু যোগ করেন)। আমি বলছি, F # এবং Boo (এবং YAML) এ রোল করুন, যদি আপনার ভাষা বিনা পোকা ছাড়াই অপঠনযোগ্য হয় তবে এটিকে ভাষার অংশ করুন।
বেনজল

48
ব্রেস যুক্ত করা যুক্তিসঙ্গত, আইএমও - সি # অবশ্যই এটিকে সমস্যা হতে আটকাতে কোনও প্রচেষ্টা করে না make এটি "ধ্রুবক == পরিবর্তনশীল" ইস্যু থেকে খুব আলাদা।
জন স্কিটি

6
a if (this! = that) {ਪ੍ਰਦਰਸ਼ਨAsSuch (); actually আসলে বেশ স্বাস্থ্যকর। "পরবর্তীতে সংযোজন" যুক্তিটি আমার কাছে ততটা (এ = 5) টাইপগুলি এড়ানো / স্পট না করার মতো ভঙ্গুর হিসাবে তত্পর করে
jpinto3912

3
@jpinto: আমি সত্যিই নিশ্চিত তুমি এখানে কি বলতে চেষ্টা করছি করছি - যে আপনি কি একক বিবৃতি প্রায় ধনুর্বন্ধনী মত, বা আপনি না হয়? এই এবং প্রশ্নের পরিবর্তনশীল ব্যবসায়ের মধ্যে পার্থক্য হ'ল সি # তে টাইপোর কোডটি অবৈধ কোড তাই সংকলক এটি বন্ধ করে দেবে। ব্রেস না লাগানোর জন্য একই কথা সত্য নয়
জোন স্কিটি

3
@ বেঞ্জল else { }যদি সেখানে পরে কিছু যোগ করার প্রয়োজন হয় এবং elseকীওয়ার্ডটি নিজেরাই লিখতে ভুলে যায় তবে সর্বদা একটি খালি ধারা সরবরাহ করতে ভুলবেন না । (জোকস)
জেপ্প স্টিগ নীলসন

12

প্রথমে নাল ব্যবহার করার একটি ভাল কারণ রয়েছে: if(null == myDuck)

যদি আপনার অপারেটরটিকে class Duckওভাররাইড করে ==, তবে if(myDuck == null)একটি অসীম লুপে যেতে পারেন।

ব্যবহার nullপ্রথম ব্যবহারসমূহ একটি ডিফল্ট সমতা comparator এবং আসলে আছে কি আপনি ইচ্ছুক ছিল।

(আমি শুনেছি আপনি শেষ পর্যন্ত সেভাবে লেখা কোডটি পড়তে অভ্যস্ত হন - আমি এখনও এই রূপান্তরটি অনুভব করতে পারি নি)।

এখানে একটি উদাহরণ:

public class myDuck
{
    public int quacks;
    static override bool operator ==(myDuck a, myDuck b)
    {
        // these will overflow the stack - because the a==null reenters this function from the top again
        if (a == null && b == null)
            return true;
        if (a == null || b == null)
            return false;

        // these wont loop
        if (null == a && null == b)
            return true;
        if (null == a || null == b)
            return false;
        return a.quacks == b.quacks; // this goes to the integer comparison
    }
}

11
এটা ভুল. Downvoted। ==অপারেটরের উপরে কেবল মাউসটি নির্দেশ করুন এবং এটি সেখানে বিশ্রাম করুন এবং আপনি দেখতে পাবেন যে ব্যবহারকারী-সংজ্ঞায়িত ওভারলোড উভয় ক্ষেত্রেই ব্যবহৃত হয় is অবশ্যই যদি এটি aআগে চেক করে bএবং তারপরে aডান অপরেন্ড থেকে বাম অপারেণ্ডের অবস্থানটি অদলবদল করে তবে এটি একটি সূক্ষ্ম পার্থক্য আনতে পারে। তবে আপনি bআগে যাচাই করতে পারেন aএবং তারপরে b == nullক্রমটিকে বিপরীত করে তোলা হবে। অপারেটরকে কল করতে এগুলি বিভ্রান্তিকর। পরিবর্তে, objectপছন্দসই ওভারলোড পেতে অপারেন্ড (বা উভয়) নিক্ষেপ করুন । লাইক if ((object)a == null)বা if (a == (object)null)
জেপ্পে স্টিগ নীলসন

10

ইতিমধ্যে প্রত্যেকের মতোই উল্লেখ করা হয়েছে এটি সি ভাষা থেকে কম-বেশি আসে যেখানে আপনি ভুল করে দ্বিতীয় চিহ্নের চিহ্নটি ভুলে গেলে ভুয়া কোড পেতে পারেন। তবে আরও একটি কারণ রয়েছে যা সি # এর সাথেও মেলে: পঠনযোগ্যতা।

এই সহজ উদাহরণটি নিন:

if(someVariableThatShouldBeChecked != null
   && anotherOne != null
   && justAnotherCheckThatIsNeededForTestingNullity != null
   && allTheseChecksAreReallyBoring != null
   && thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded != null)
{
    // ToDo: Everything is checked, do something...
}

আপনি যদি সমস্ত নাল শব্দটিকে শুরুতে সরিয়ে নিতে চান তবে আপনি খুব সহজেই সমস্ত চেক খুঁজে পেতে পারেন:

if(null != someVariableThatShouldBeChecked
   && null != anotherOne
   && null != justAnotherCheckThatIsNeededForTestingNullity
   && null != allTheseChecksAreReallyBoring
   && null != thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded)
{
    // ToDo: Everything is checked, do something...
}

সুতরাং এই উদাহরণটি একটি খারাপ উদাহরণ হতে পারে (কোডিং নির্দেশিকাগুলি উল্লেখ করুন) তবে কেবল একটি সম্পূর্ণ কোড ফাইলের মধ্যে আপনার দ্রুত স্ক্রোল সম্পর্কে ভাবেন। কেবল প্যাটার্নটি দেখে

if(null ...

আপনি তাত্ক্ষণিকভাবে জানেন যে কী ঘটছে।

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


9

আমার ধারণা এটি একটি সি প্রোগ্রামার যা ভাষা পরিবর্তন করেছে sw

সি, আপনি নিম্নলিখিত লিখতে পারেন:

int i = 0;
if (i = 1)
{
    ...
}

সেখানে একটি একক সমান চিহ্নের ব্যবহার লক্ষ্য করুন, যার অর্থ কোডটি ভ্যারিয়েবল i কে 1 বরাদ্দ করবে, তারপরে 1 টি ফিরে আসবে (একটি অ্যাসাইনমেন্ট একটি এক্সপ্রেশন) এবং if-স্টেটমেন্টে 1 ব্যবহার করবে, যা সত্য হিসাবে পরিচালনা করা হবে। অন্য কথায়, উপরেরটি একটি বাগ।

সি # তে তবে এটি সম্ভব নয়। দুজনের মধ্যে আসলেই কোনও পার্থক্য নেই।


1
সংকলক অভিযোগ না করে "সি # তে তবে এটি সম্ভব নয়", যেমন যদি বিবৃতিতে বুলিয়ান এক্সপ্রেশন প্রয়োজন হয় এবং প্রদত্ত বিবরণটি টাইপ ইন্টের হয়।
রবার্ট হার্ভে

4

আগের যুগে লোকেরা ভুলে যেত '!' (বা সাম্যের জন্য অতিরিক্ত '=' যা স্পট করা আরও বেশি কঠিন) এবং তুলনার পরিবর্তে একটি অ্যাসাইনমেন্ট করুন। নালটি সামনে রাখলে বাগের সম্ভাবনা দূর হয়, যেহেতু নাল কোনও এল-মান হয় না (IE এটি বরাদ্দ করা যায় না)।

আপনি আজকাল শর্তসাপেক্ষে কোনও অ্যাসাইনমেন্ট করলে বেশিরভাগ আধুনিক সংকলকরা একটি সতর্কতা দেয় এবং সি # আসলে একটি ত্রুটি দেয়। বেশিরভাগ লোকেরা কেবল var == নাল স্কিমের সাথে লেগে থাকে কারণ কিছু লোকের পক্ষে পড়া সহজ।


সকল সি # কম্পাইলার (নোট এই একটি সি # প্রশ্ন হল) কম্পাইল করতে ব্যর্থ উচিত একটি "যদি" বিবৃতি যেখানে অভিব্যক্তি একটি বুলিয়ান যদিও ... নয়
জন স্কিট

4

আমি এই সম্মেলনটি অনুসরণ করে কোনও সুবিধা দেখছি না। সিতে, যেখানে বুলিয়ান ধরণের অস্তিত্ব নেই, এটি লেখার পক্ষে কার্যকর

if( 5 == variable)

বরং

if (variable == 5)

কারণ আপনি যদি একের এক চিহ্নটি ভুলে যান তবে আপনি শেষ হয়ে যাবেন

if (variable = 5)

যা ভেরিয়েবলকে 5 প্রদান করে এবং সর্বদা সত্যের জন্য মূল্যায়ন করে। তবে জাভাতে, একটি বুলিয়ান একটি বুলিয়ান। এবং সাথে! = এর কোনও কারণ নেই।

একটি ভাল পরামর্শ, যদিও, লিখতে হয়

if (CONSTANT.equals(myString))

বরং

if (myString.equals(CONSTANT))

কারণ এটি নালপয়েন্টারএক্সেপশনগুলি এড়াতে সহায়তা করে।

আমার পরামর্শটি হ'ল নিয়মের ন্যায়সঙ্গততা চাওয়া। যদি কিছুই না থাকে তবে কেন এটি অনুসরণ করবেন? এটি পঠনযোগ্যতা সাহায্য করে না


0

আমার কাছে আপনি সর্বদা পছন্দ করেন যে আপনি কোন স্টাইল পছন্দ করেন

@ শাই - তারপরে আবারও যদি আপনি অপারেটরগুলিকে বিভ্রান্ত করেন তবে আপনার একটি সংকলন ত্রুটি পাওয়া উচিত বা আপনি একটি বাগ দিয়ে কোড চালাবেন - একটি বাগ যা ফিরে এসে আপনাকে পরে রাস্তায় কামড় দেয় যেহেতু এটি অপ্রত্যাশিত আচরণের জন্ম দেয় since


আমি মনে করি না যে আমি সুরক্ষার কারণ ছাড়া অন্য কোনও "ধ্রুবক == পরিবর্তনশীল" ফর্মটিকে বেশি পছন্দ করতে শুনেছি , যা ইতিমধ্যে সি # তে মোকাবেলা করা হয়েছে।
জন স্কিটি

আমি নিজেকে "পরিবর্তনশীল == ধ্রুবক" পছন্দ করি, তবে আমি প্রোগ্রামাররা বিপরীতগুলি গ্রহণ করতে দেখেছি কারণ তারা মনে করেন যে এটি তাদের কাছে আরও প্রাকৃতিকভাবে পড়ে।
TheCodeJunkie

1
তারা কি বছরের পর বছর সি-এর ব্রেইন ওয়াশিংয়ের সমস্ত লোক ছিল, নাকি এটি একটি আসল পছন্দ ছিল?
জন স্কিটি

0

অনেকগুলি নির্দেশিত হিসাবে, এটি বেশিরভাগ পুরানো সি কোডে এটি সংকলন ত্রুটি সনাক্ত করতে ব্যবহৃত হয়েছিল, কারণ সংকলক এটি আইনী হিসাবে মেনে নিয়েছে

জাভা, গো এর মতো নতুন প্রোগ্রামিংয়ের ভাষা এ জাতীয় সংকলন ত্রুটি ক্যাপচার করার জন্য যথেষ্ট স্মার্ট

কোডে অবস্থিত শর্তগুলির মতো "নাল! = পরিবর্তনশীল" ব্যবহার করা উচিত নয় কারণ এটি খুব অপঠনযোগ্য


-4

আরও একটি জিনিস ... আপনি যদি কোনও স্থির সাথে একটি চলকটির তুলনা করে থাকেন (প্রাক্তনের জন্য পূর্ণসংখ্যা বা স্ট্রিং) the

int i;
if(i==1){        // Exception raised: i is not initialized. (C/C++)
  doThis();
}

যেহেতু

int i;
if(1==i){        // OK, but the condition is not met.
  doThis();
}

এখন, যেহেতু ডিফল্টরূপে সি # সমস্ত ভেরিয়েবল ইনস্ট্যান্ট করে, সেই ভাষায় আপনার সেই সমস্যাটি হওয়া উচিত নয়।


1
আপনি কোডের প্রথম বিটের জন্য কোন সংকলকটি ব্যবহার করছেন তা আমি নিশ্চিত নই, তবে এটি সংকলন করা উচিত (সাধারণত একটি সতর্কতা সহ)। I এর মান অপরিজ্ঞাত, তবে এর কিছু মান আছে।
ডলফিন

উভয় কোড অবশ্যই সংকলন করা হবে! ঠিক এটাই সমস্যা। প্রথম কোডটি চালনার চেষ্টা করুন এবং আপনি বুঝতে পারবেন "ব্যতিক্রম উত্থাপিত" বলতে কী বোঝাতে চেয়েছিল ...
কারলিপপিন্স

উভয় মধ্যে পার্থক্য পেতে না। আপনি কি বর্ণনা করতে পারেন?
এমফাজেকাস

আপনি যদি সি / সি ++ তে ইনট * i ঘোষণা না করেন, এবং এমনকি সেই ক্ষেত্রে এটি পয়েন্টারগুলির সাথে তুলনা করে এবং কোনও ব্যতিক্রম ছুঁড়ে না ফেলে ... কোনও ডলফিনের মত মান অপরিবর্তিত থাকলেও এটি কোনও ব্যতিক্রম তৈরি করে না No
Cobusve

কোনও ব্যতিক্রম নয়, আসুন ধরা যাক iএকটি যথাযথ সূচনা ছাড়াই একটি এলোমেলো মান। সি / সি ++ তে এক্সপ্রেশনটি সম্পূর্ণ একই শব্দার্থক
রফিয়েলো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.