একটি বাতিল পদ্ধতিতে রিটার্ন ব্যবহার করা কি খারাপ অভ্যাস?


92

নিম্নলিখিত কোডটি কল্পনা করুন:

void DoThis()
{
    if (!isValid) return;

    DoThat();
}

void DoThat() {
    Console.WriteLine("DoThat()");
}

একটি শূন্য পদ্ধতিতে কোনও রিটার্ন ব্যবহার করা ঠিক কি? এটির কোনও কার্যকারিতা জরিমানা আছে? অথবা এই জাতীয় কোড লিখতে ভাল হবে:

void DoThis()
{
    if (isValid)
    {
        DoThat();
    }
}
c#  return  void 

4
কী সম্পর্কে: অকার্যকর DoThis () {if (isValid) DoThat (); }
ডিসকোডাক

30
কোড কল্পনা? কেন? এটা ঠিক আছে! :-D
STW

এটি ভাল প্রশ্ন, আমি সবসময় মনে করি রিটার্ন ব্যবহার করা ভাল অভ্যাস; পদ্ধতি বা ফাংশন থেকে প্রস্থান করতে। বিশেষত একটি লিনকিউ ডেটা মাইনিং পদ্ধতিতে একাধিক আইকিউয়েরেবল <T> ফলাফল রয়েছে এবং এগুলি সমস্ত একে অপরের উপর নির্ভর করে। তাদের মধ্যে যদি কোনও ফলাফল না থাকে তবে সতর্কতা অবলম্বন করুন এবং প্রস্থান করুন।
চেউং

উত্তর:


173

শূন্য পদ্ধতিতে ফিরে আসা খারাপ নয়, বাসা বাঁধতে কমাতে বিবৃতি উল্টে ফেলার একটি সাধারণ অভ্যাস practiceif

এবং আপনার পদ্ধতিগুলিতে কম বাসা বাঁধলে কোডের পাঠযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতা উন্নত হয়।

প্রকৃতপক্ষে যদি কোনও রিটার্ন বিবৃতি ছাড়াই আপনার শূন্য পদ্ধতি থাকে তবে সংকলকটি সর্বদা এটির শেষে একটি ret নির্দেশ জেনারেট করে।


33

গার্ডগুলি ব্যবহার করার আরও একটি দুর্দান্ত কারণ রয়েছে (নেস্টেড কোডের বিপরীতে): অন্য প্রোগ্রামার যদি আপনার ফাংশনে কোড যুক্ত করে, তবে তারা নিরাপদ পরিবেশে কাজ করছে।

বিবেচনা:

void MyFunc(object obj)
{
    if (obj != null)
    {
        obj.DoSomething();
    }
}

বনাম:

void MyFunc(object obj)
{
    if (obj == null)
        return;

    obj.DoSomething();
}

এখন, কল্পনা করুন যে অন্য প্রোগ্রামার লাইনটি যুক্ত করেছে: obj.DoSomethingElse ();

void MyFunc(object obj)
{
    if (obj != null)
    {
        obj.DoSomething();
    }

    obj.DoSomethingElse();
}

void MyFunc(object obj)
{
    if (obj == null)
        return;

    obj.DoSomething();
    obj.DoSomethingElse();
}

অবশ্যই এটি একটি সরল ঘটনা, তবে প্রোগ্রামার প্রথম (নেস্টেড কোড) উদাহরণে প্রোগ্রামটিতে ক্র্যাশ যুক্ত করেছে। দ্বিতীয় উদাহরণে (প্রহরীদের সাথে প্রারম্ভিক প্রস্থান), একবার আপনি প্রহরীটি পেরিয়ে গেলে, আপনার কোড নাল রেফারেন্সের অনিচ্ছাকৃত ব্যবহার থেকে নিরাপদ।

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


হ্যাঁ, তবে অন্যদিকে, বাসা বাঁধার বেশ কয়েকটি স্তর তাদের শর্তাদি সহ কোডটিকে বাগের কাছে আরও প্রবণ করে তোলে, যুক্তিটিকে ট্র্যাক করা আরও কঠিন এবং - আরও গুরুত্বপূর্ণভাবে - ডিবাগ করা আরও শক্ত। ফ্ল্যাট ক্রিয়াকলাপগুলি আরও কম মন্দ, আইএমও।
স্ক্রিম

18
আমি কমেছে বাসা বাঁধার পক্ষে ! :-)
জেসন উইলিয়ামস

আমি এটার সাথে একমত. এছাড়াও, একটি রিফ্যাক্টর স্ট্যান্ড পয়েন্ট থেকে, যদি রেজিস্টর স্ট্রাক্ট হয়ে যায় বা আপনি যে গ্যারান্টি দিতে পারেন এমন কিছু বাতিল হয় না তবে পদ্ধতিটি রিফ্যাক্টর করা সহজ এবং নিরাপদ।
ফিল কুপার

18

খারাপ অভ্যাস ??? কোনভাবেই না. প্রকৃতপক্ষে, বৈধতা যদি ব্যর্থ হয় তবে তাড়াতাড়ি পদ্ধতি থেকে ফিরে বৈধতাগুলি পরিচালনা করা ভাল। অন্যথায় এটি বিপুল পরিমাণ নেস্টেড আইএফস এবং এলেসের ফলস্বরূপ। তাড়াতাড়ি সমাপ্তি কোড পঠনযোগ্যতার উন্নতি করে।

একই অনুরূপ প্রশ্নের প্রতিক্রিয়াগুলিও যাচাই করুন: আমি যদি অন্য-এর পরিবর্তে রিটার্ন / চালিয়ে যাওয়া বিবৃতি ব্যবহার করি?


8

এটি খারাপ অনুশীলন নয় (ইতিমধ্যে বর্ণিত সমস্ত কারণে) যাইহোক, কোনও পদ্ধতিতে আপনার যত বেশি রিটার্ন আসবে, ততই এটি ছোট লজিক্যাল পদ্ধতিতে বিভক্ত হওয়ার সম্ভাবনা তত বেশি।


8

প্রথম উদাহরণটি গার্ড স্টেটমেন্ট ব্যবহার করা। উইকিপিডিয়া থেকে :

কম্পিউটার প্রোগ্রামিংয়ে, একজন প্রহরী একটি বুলিয়ান এক্সপ্রেশন যা সঠিকভাবে মূল্যায়ন করতে হবে যদি প্রোগ্রামের কার্যনির্বাহী প্রশ্নে শাখায় চলতে থাকে।

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

সুতরাং সাধারণভাবে এটি এটি পছন্দ করবে:

void DoThis()
{
  if (guard1) return;
  if (guard2) return;
  ...
  if (guardN) return;

  DoThat();
}

আমি মনে করি এটি তখন অনেক বেশি পাঠযোগ্য:

void DoThis()
{
  if (guard1 && guard2 && guard3)
  {
    DoThat();
  }
}

3

কোনও পারফরম্যান্স পেনাল্টি নেই, তবে কোডের দ্বিতীয় অংশটি আরও বেশি পঠনযোগ্য এবং তাই বজায় রাখা সহজ।


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

আমি এর সাথে একমত নই। বাড়া বাড়ানো পড়ার যোগ্যতার উন্নতি করে না। কোডের প্রথম টুকরাটি "গার্ড" বিবৃতি ব্যবহার করছে, যা পুরোপুরি বোঝা যায় pattern
সিডিএমকেই

আমিও দ্বিমত পোষণ করি। গার্ড ক্লজগুলি যা কোনও কার্যের প্রথম দিকে জামিন দেয় তা সাধারণত আজকাল পাঠককে বাস্তবায়ন বুঝতে সহায়তা করার জন্য একটি ভাল জিনিস হিসাবে বিবেচিত হয়।
পিট হজসন

2

এই ক্ষেত্রে, আপনার দ্বিতীয় উদাহরণটি আরও ভাল কোড, তবে এটি একটি শূন্য ফাংশন থেকে ফিরে আসার সাথে কিছুই করার নেই, এটি কেবল কারণ দ্বিতীয় কোডটি আরও সরাসরি। তবে একটি অকার্যকর ফাংশন থেকে ফিরে আসা পুরোপুরি ঠিক।


0

এটি পুরোপুরি ঠিক আছে এবং কোনও 'পারফরম্যান্স পেনাল্টি' নয়, তবে বন্ধনী ছাড়াই কখনও 'if' বিবৃতি লিখবেন না।

সর্বদা

if( foo ){
    return;
}

এটি আরও পাঠযোগ্য; এবং আপনি দুর্ঘটনাক্রমে কখনই ধরে নিতে পারবেন না যে কোডের কিছু অংশ যখন না থাকে তখন সেই বিবৃতিতে থাকে।


4
পাঠযোগ্য বিষয়বস্তু। ইমো, কোডে যুক্ত হওয়া যে কোনও কিছু যা অপ্রয়োজনীয় তা কম পাঠযোগ্য করে তোলে ... (এবং আমাকে আরও পড়তে হবে, এবং তখন আমি ভাবছি কেন এটি সেখানে রয়েছে এবং আমি কিছু মিস করছি না তা নিশ্চিত করার চেষ্টা করে সময় নষ্ট করছি) ... তবে এটি আমার বিষয়গত মতামত
চার্লস ব্রেটানা

10
ব্রেসগুলি সর্বদা অন্তর্ভুক্ত করার আরও ভাল কারণ হ'ল পঠনযোগ্যতা সম্পর্কে কম এবং সুরক্ষা সম্পর্কে। ধনুর্বন্ধনী ব্যতীত কারও কারও পক্ষে পরে বাগ হিসাবে ঠিক করা খুব সহজ, যদি খুব মনোযোগ না দেওয়া এবং ধনুর্বন্ধনী যোগ না করে এগুলিকে যুক্ত না করে তবে এই বাগের অতিরিক্ত হিসাবে অতিরিক্ত বিবৃতি প্রয়োজন। ধনুর্বন্ধনী সহ সবসময় অন্তর্ভুক্ত করে, এই ঝুঁকিটি দূর হয়।
স্কট ডরম্যান

4
সিল্কি, আপনার আগে প্রবেশ করুন টিপুন {। এই একই কলামে আপনার {সাথে এই লাইনগুলি }প্রবাহিত করে, যা পঠনযোগ্যতাকে ব্যাপকভাবে সহায়তা করে (সম্পর্কিত উন্মুক্ত / ঘনিষ্ঠ বন্ধনীগুলির সন্ধান করা অনেক সহজ)।
চিত্রশিল্পী

4
@ ইমাজিস্ট আমি এটিকে ব্যক্তিগত পছন্দকে ছেড়ে যাব; এবং এটি আমার পছন্দ
দুপুর সিল্ক

4
যদি প্রতিটি ঘনিষ্ঠ-ব্রেস একটি ওপেন-ব্রেসের সাথে মিলে যায় যা ইন্ডেন্টের একই স্তরে স্থাপন করা হয় , তবে কোন ifবিবৃতিতে ঘনিষ্ঠ ধনুর্বন্ধনী প্রয়োজন তা দৃষ্টিভঙ্গিভাবে পৃথক করা সহজ হবে, এবং এইভাবে ifএকটি বিবৃতি নিয়ন্ত্রণ করা নিরাপদ থাকবে। ওপেন-ব্রেসকে লাইনে ফিরে ধাক্কা দিয়ে ifপ্রতিটি বহু-বিবৃতিতে উল্লম্ব স্থানের একটি রেখা সংরক্ষণ করে if, তবে অন্যথায়-অপ্রয়োজনীয় ক্লোস-ব্রেস লাইন ব্যবহার করা প্রয়োজন।
সুপারক্যাট

0

আমি এই এক আপনার যুব হুইপারস্পেনারদের সাথে একমত নই।

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

প্রাথমিক নিয়মটি হ'ল প্রতিটি নিয়ন্ত্রণ কাঠামো, এবং প্রতিটি মডিউলগুলির ঠিক একটি প্রবেশ এবং একটি প্রস্থান থাকা উচিত। মডিউলটির মাঝামাঝি একটি স্পষ্ট প্রত্যাবর্তন সেই নিয়মকে ভেঙে দেয় এবং প্রোগ্রামের অবস্থা সম্পর্কে তর্ক করা আরও শক্ত করে তোলে, যার ফলে প্রোগ্রামটি সঠিক কিনা না তা বলা শক্ত করে তোলে (যা আরও শক্তিশালী সম্পত্তি) "এটি কাজ করে না প্রদর্শিত হবে কিনা" এর চেয়ে বেশি)।

"গোটোর বিবৃতি ক্ষতিকারক হিসাবে বিবেচিত হয়" এবং "স্ট্রাকচার্ড প্রোগ্রামিং" 1970 এর দশকের "স্ট্রাকচার্ড প্রোগ্রামিং" বিপ্লব শুরু করেছিল। এই দুটি টুকরোগুলি হ'ল আমাদের যদি-তবে-অন্যদিকে, করণীয়, এবং অন্যান্য স্পষ্ট নিয়ন্ত্রণ নিয়ন্ত্রণ রয়েছে এবং উচ্চ-স্তরের ভাষাগুলিতে কেন GOTO বিবৃতি বিপন্ন প্রজাতির তালিকায় রয়েছে। (আমার ব্যক্তিগত মতামতটি হচ্ছে তাদের বিলুপ্ত প্রজাতির তালিকায় থাকা দরকার।)

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

এটিও উল্লেখযোগ্য যে নিক্লাস রাইথ ওবেরন -07-এ রিটার্নের বিবৃতিটির অর্থার্থক শব্দটি বদলে দিয়েছিল, এটি ওবারন প্রোগ্রামিং ভাষার সর্বশেষতম সংস্করণ, এটি একটি টাইপ করা পদ্ধতি (যেমন, ফাংশন) এর ঘোষণার পিছনের অংশ হিসাবে তৈরি করেছিল ফাংশনটির শরীরে এক্সিকিউটেবল স্টেটমেন্ট। পরিবর্তনের তাঁর ব্যাখ্যা বলেছেন যে তিনি এটা অবিকল করেনি কারণ পূর্ববর্তী ফর্ম ছিলেন স্ট্রাকচার্ড প্রোগ্রামিং এক-প্রস্থান নীতি লঙ্ঘন।


4
@ জন: আমরা পাসকালের (আমাদের বেশিরভাগই, যাইহোক) কাটিয়ে ওঠার প্রায় একাধিক রিটার্ন সম্পর্কে ডাইকস্ট্রার আদেশ পেয়েছি।
জন স্যান্ডার্স

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

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

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

@ জেসন: মূল প্রশ্নটি গার্ডের বক্তব্য সম্পর্কে বিশেষত ছিল না, তবে একটি পদ্ধতির মাঝখানে এলোমেলো রিটার্নের বিবৃতি সম্পর্কে ছিল। উদাহরণ দেওয়া হয়েছে প্রহরী হিসাবে সম্মিলিত উদাহরণ। মূল সমস্যাটি হ'ল, রিটার্ন সাইটে আপনি পদ্ধতিটি কী করেছে বা কী করে নি সে সম্পর্কে আপনি যুক্তি অর্জন করতে সক্ষম হতে চান এবং এলোমেলো গোটগুলি একই কারণে যে এলোমেলোভাবে GOTOs তাকে আরও শক্ত করে তোলে ঠিক তা কারণেই এলোমেলোভাবে রিটার্নগুলি আরও শক্ত করে তোলে। দেখুন: ডিজকস্ট্র, "গোটোর বিবৃতি ক্ষতিকারক হিসাবে বিবেচিত হয়"। সিনট্যাক্সের দিকে, সিডিএমকেএ অন্য জবাব দিয়েছিল, তার প্রহরীদের পক্ষে তার পছন্দসই বাক্য গঠন; কোন ফর্মটি বেশি পঠনযোগ্য তা নিয়ে আমি তার মতামতের সাথে একমত নই।
জন আর স্ট্রোহম

0

প্রহরীগুলি ব্যবহার করার সময়, নিশ্চিত করুন যে আপনি পাঠকদের বিভ্রান্ত না করার জন্য নির্দিষ্ট নির্দেশিকা অনুসরণ করেছেন।

  • ফাংশন একটি কাজ করে
  • গার্ডরা কেবল ফাংশনে প্রথম যুক্তি হিসাবে পরিচয় হয়
  • unnested অংশ ফাংশনের রয়েছে কোর অভিপ্রায়

উদাহরণ

// guards point you to the core intent
void Remove(RayCastResult rayHit){

  if(rayHit== RayCastResult.Empty)
    return
    ;
  rayHit.Collider.Parent.Remove();
}

// no guards needed: function split into multiple cases
int WonOrLostMoney(int flaw)=>
  flaw==0 ? 100 :
  flaw<10 ? 30 :
  flaw<20 ? 0 :
  -20
;

-3

বস্তু নাল ইত্যাদি হলে কিছুই ফিরিয়ে দেওয়ার পরিবর্তে ব্যতিক্রম নিক্ষেপ করুন

আপনার পদ্ধতিটি প্রত্যাশা করে যে বস্তুটি শূন্য হবে না এবং এটি ক্ষেত্রে নয় তাই আপনার ব্যতিক্রম ছড়িয়ে দেওয়া উচিত এবং কলারটিকে এটি পরিচালনা করতে দেওয়া উচিত।

তবে তাড়াতাড়ি ফেরা অন্যথায় খারাপ অভ্যাস নয়।


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