ফোরচ লুপে নাল পরীক্ষা করুন


97

নিম্নলিখিত
কাজগুলি করার একটি দুর্দান্ত উপায় আছে: আমার ফাইলটিতে নালার জন্য একটি চেক দরকার। লুপটি এগিয়ে যাওয়ার আগে হায়দাররা

if (file.Headers != null)
{
  foreach (var h in file.Headers)
  {
   //set lots of properties & some other stuff
  }
}

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

এমন কিছু যা মূল্যায়ন করবে

foreach(var h in (file.Headers != null))
{
  //do stuff
}

সম্ভব?


4
: আপনি এখানে একটি চেহারা থাকতে পারে stackoverflow.com/questions/6937407/...
আদ্রিয়ান Fâciu

stackoverflow.com/questions/872323/… অন্য ধারণা।
weismat

4
@ অ্যাড্রিয়ানফ্যাসিউ আমার ধারণা এটি সম্পূর্ণ আলাদা। প্রতিটি পরীক্ষা-নিরীক্ষার আগে সংগ্রহটি শূন্য হয় কিনা তা প্রশ্নটি পরীক্ষা করে। সংগ্রহে থাকা আইটেমটি শূন্য হলে আপনার লিঙ্কটি পরীক্ষা করে।
rikitikitik


4
সি # 8 তে কেবল কোনও ধরণের শূন্য-শর্তযুক্ত ভবিষ্যদ্বাণী থাকতে পারে, যেমন সিনট্যাক্স: ফোরচ? (আমি সংগ্রহের ক্ষেত্রে) {} আমি মনে করি এটি যথাযথ করার পক্ষে একটি সাধারণ যথেষ্ট দৃশ্যাবলী এবং এখানে যে ভাষাটি বোঝানো হয়েছে তাতে সাম্প্রতিক শূন্য-শর্ত যুক্ত হয়েছে?
এমএমএস

উত্তর:


126

রুনের পরামর্শে সামান্য কসমেটিক সংযোজন হিসাবে আপনি নিজের এক্সটেনশন পদ্ধতি তৈরি করতে পারেন:

public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

তারপরে আপনি লিখতে পারেন:

foreach (var header in file.Headers.OrEmptyIfNull())
{
}

স্বাদ অনুযায়ী নাম পরিবর্তন করুন :)


80

ধরে নিচ্ছি যে ফাইলের উপাদানগুলির ধরণ e হায়ডাররা টি হয় আপনি এটি করতে পারেন

foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
  //do stuff
}

এটি যদি ফাইলের খালি গণনার তৈরি করে। যদি ফাইলের ধরণটি আপনার নিজের ধরণের হয় তবে আমি তার Headersপরিবর্তে গিটারটি পরিবর্তন করা বিবেচনা করব । nullঅজানা এর মান তাই যদি সম্ভব হয় তবে "আমি জানি কোন উপাদান নেই" হিসাবে নাল ব্যবহার করার পরিবর্তে নাল আসলে (/ মূলত) ব্যাখ্যা করা উচিত "কোনও উপাদান আছে কিনা তা আমি জানি না" প্রদর্শন করার জন্য একটি খালি সেট ব্যবহার করুন আপনি জানেন যে সেটে কোনও উপাদান নেই। এটিও DRY'er হবে যেহেতু আপনাকে প্রায়শই নাল চেক করতে হবে না।

জোনস পরামর্শের অনুসরণ হিসাবে সম্পাদনা করুন, আপনি উপরের কোডটি পরিবর্তন করে একটি এক্সটেনশন পদ্ধতিও তৈরি করতে পারেন

foreach(var header in file.Headers.OrEmptyIfNull()){
  //do stuff
}

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

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

public static IList<T> OrEmptyIfNull<T>(this IList<T> source)
{
    return source ?? Array.Empty<T>();
}

@ কেজবার্টেলের উত্তর ("স্ট্যাকওভারফ্লো.com/a/32134295/401246" এ সলিউশন সলিউশন, কারণ এটি নেই: ক) nullপুরো লুপের এলসিডির (অবধি IEnumerable<T>ব্যবহার হিসাবে ) অবক্ষয়জনিত কর্মক্ষমতা অবনতির সাথে জড়িত ? হবে), খ) প্রতিটি প্রকল্পে একটি এক্সটেনশন পদ্ধতি যুক্ত করা প্রয়োজন, বা গ) null IEnumerables(পিউফফ্ট! পুহ-লেইজ! এসএমএইচ।) শুরু করতে হবে (কুজ nullমানে এন / এ, যেখানে খালি তালিকার অর্থ এটি প্রয়োগযোগ্য তবে বর্তমানে, ভাল, খালি !, অর্থাত্ কোনও কর্মচারীর এমন কমিশন থাকতে পারে যেগুলি বিক্রয়হীন জন্য N / A বা বিক্রয়ের জন্য খালি রাখতে হবে যখন তারা কোনও আয় করেনি)।
টম

@ এক নাল থেকে আলাদা করে পরীক্ষা করুন যেসব ক্ষেত্রে শূণ্যকারী বাতিল নয় সেগুলির জন্য কোনও জরিমানা নেই। গণনা শূন্য নয় তা নিশ্চিত করার সময়ও এই চেকটি এড়ানো অসম্ভব। উপরের কোডটিতে শিরোনামের একটি প্রয়োজন IEnumerable যা foreachপ্রয়োজনগুলির তুলনায় আরও সীমাবদ্ধ তবে List<T>আপনি যে উত্তরটিতে লিঙ্ক করেছেন তার প্রয়োজনের চেয়ে কম সীমাবদ্ধ । যার পরীক্ষার সমান পারফরম্যান্স পেনাল্টি রয়েছে যা গণনা শূন্য কিনা।
রুন এফএস

আমি Kjbartel এর উত্তর হিসাবে একই থ্রেডে ভ্লাদ বেজডেনের উত্তর সম্পর্কে এরিক লিপার্টের মন্তব্যে "এলসিডি" ইস্যুটি ভিত্তি করেছিলাম: "@ কোডেআইনচ্যাওস: আহ, আমি এখন আপনার বক্তব্যটি দেখছি। সংকলক যখন সনাক্ত করতে পারে যে" ফোরচ "পুনরাবৃত্তি হচ্ছে একটি তালিকার <T> বা একটি অ্যারের উপরে তারপরে এটি ভ্যালু-টাইপ এনুমিরেটরগুলি ব্যবহার করতে বা বাস্তবে একটি "ফর" লুপ তৈরি করতে অগ্রণীটিকে অনুকূলিত করতে পারে When সর্বনিম্ন সাধারণ ডিনোমিনেটর "কোডজেন, যা কিছু ক্ষেত্রে ধীর হতে পারে এবং আরও মেমরির চাপ তৈরি করতে পারে ...."। এটি প্রয়োজন সম্মত হন List<T>
টম

@ টম উত্তরের ভিত্তিটি হ'ল ফাইল। হায়ডাররা একটি অনুমিত <<> এই ক্ষেত্রে সংকলক অপ্টিমাইজেশন করতে পারে না। এটি এড়াতে এক্সটেনশন পদ্ধতির সমাধানটি প্রসারিত করার পরিবর্তে সোজা এগিয়ে। সম্পাদনা দেখুন
রুন এফএস

19

স্পষ্টতই, আমি পরামর্শ দিচ্ছি: কেবল nullপরীক্ষাটি শেষ কর। একটি nullপরীক্ষা মাত্র একটি brfalseবা brfalse.s; অন্য সব কিছুর আরো অনেক কিছু কাজ (পরীক্ষা বরাদ্দকরণ, অতিরিক্ত পদ্ধতি কল, অপ্রয়োজনীয় জড়িত যাচ্ছে GetEnumerator(), MoveNext(), Dispose()পুনরুক্তিকারীর উপর, ইত্যাদি)।

একটি ifপরীক্ষা সহজ, সুস্পষ্ট এবং দক্ষ।


4
আপনি একটি আকর্ষণীয় পয়েন্ট মার্ক করতে পারেন, যাইহোক, আমি বর্তমানে কোড এর ইন্ডেন্টেশন স্তর কমাতে খুঁজছি। আমি যখন আমার পারফরম্যান্সের নোট নেওয়ার প্রয়োজন হয় তখন আমি আপনার মন্তব্যটি মাথায় রাখব।
এমিনেম

4
এই মার্কের উপর একটি দ্রুত নোট .. আমি এই প্রশ্নটি জিজ্ঞাসা করার কয়েক বছর পরে এবং কিছু কার্য সম্পাদন বর্ধন করার দরকার পরে, আপনার পরামর্শটি অত্যন্ত কার্যকর হয়েছিল। আপনাকে ধন্যবাদ
এমিনেম

13

"যদি" পুনরাবৃত্তিটি ঠিক হওয়ার আগে, তবে "সুন্দর" শব্দার্থকগুলির মধ্যে কয়েকটি আপনার কোডটি কম পঠনযোগ্য করতে পারে।

যাইহোক, যদি ইন্ডেন্টেশনটি আপনার বিরক্ত করে, আপনি যদি পরীক্ষা করতে চান তবে এটি পরিবর্তন করতে পারেন:

if(file.Headers == null)  
   return;

এবং আপনি কেবল তখন শীর্ষস্থানীয় লুপটিতে পৌঁছে যাবেন যখন শিরোনামের সম্পত্তিটিতে সত্যিকারের মান থাকে।

আমি ভাবতে পারি এমন অন্য একটি বিকল্পটি হ'ল আপনার ফোরচ লুপের ভিতরে নাল-কোলেসিং অপারেটরটি ব্যবহার করা এবং নাল চেক করা সম্পূর্ণরূপে এড়াতে। নমুনা:

List<int> collection = new List<int>();
collection = null;
foreach (var i in collection ?? Enumerable.Empty<int>())
{
    //your code here
}

(আপনার সত্য বস্তু / প্রকারের সাথে সংগ্রহটি প্রতিস্থাপন করুন)


যদি বিবৃতিটির বাইরে কোনও কোড থাকে তবে আপনার প্রথম বিকল্পটি কাজ করবে না।
rikitikitik

আমি সম্মত হই, কেবল কোড বিউটিফিকেশনের জন্য, নতুন তালিকা তৈরি করার তুলনায় যদি বিবৃতিটি কার্যকর করা সহজ এবং সস্তা হয়।
আন্দ্রেস জোহানসন

11

ব্যবহার নাল-শর্তাধীন অপারেটর এবং foreach () যা দ্রুত মান foreach লুপ চেয়ে কাজ করে।
যদিও আপনাকে সংগ্রহটি তালিকায় কাস্ট করতে হবে।

   listOfItems?.ForEach(item => // ... );

4
দয়া করে আপনার উত্তরের চারপাশে কিছু ব্যাখ্যা যুক্ত করুন, কেবল একটি কোড ওয়ান-লাইনারের চেয়ে এই সমাধানটি কেন কাজ করে তা স্পষ্টভাবে জানিয়ে দিন
লর্ডউইলমোর

আমার মামলার সেরা সমাধান
জোসেফ হেনেন

3

এই পরিস্থিতিগুলির জন্য আমি একটি দুর্দান্ত সামান্য এক্সটেনশন পদ্ধতি ব্যবহার করছি:

  public static class Extensions
  {
    public static IList<T> EnsureNotNull<T>(this IList<T> list)
    {
      return list ?? new List<T>();
    }
  }

শিরোনামগুলি টাইপের তালিকায় রয়েছে তা প্রদত্ত, আপনি নিম্নলিখিতগুলি করতে পারেন:

foreach(var h in (file.Headers.EnsureNotNull()))
{
  //do stuff
}

4
আপনি ??অপারেটরটি ব্যবহার করতে পারেন এবং রিটার্নের বিবৃতিটি ছোট করতে পারেনreturn list ?? new List<T>;
রুন এফএস

4
@ ওল্ফগাংজিগেলার, আমি যদি সঠিকভাবে বুঝতে পারি যে nullআপনার নমুনায় পরীক্ষার file.Headers.EnsureNotNull() != nullপ্রয়োজন হয় না, এবং এমনকি ভুলও না?
রিমকো জানসেন

0

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

এই পদ্ধতির নাম দেওয়া ভাল হবে NewIfDefault। এটি কেবল সংগ্রহের জন্যই কার্যকর হতে পারে, তাই টাইপ সীমাবদ্ধতা IEnumerable<T>হতে পারে অনর্থক।

public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
        where TCollection: class, IEnumerable<T>, new()
    {
        return collection ?? new TCollection();
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.