যদি (আইটেম! = নাল) পূর্বাভাসের আগে অতিরিক্ত জিনিস (টি আইটেমের আইটেম) হয়?


109

আমি প্রায়শই নীচের মত কোড জুড়ে আসি:

if ( items != null)
{
   foreach(T item in items)
   {
        //...
   }
}

মূলত, ifশর্তটি নিশ্চিত করে যে foreachব্লকটি itemsশূন্য না হলে কেবল কার্যকর করা হবে । আমি ভাবছি ifশর্তটি আসলেই প্রয়োজন কিনা , বা foreachযদি কেসটি পরিচালনা করে তবে items == null

মানে, আমি কি সহজভাবে লিখতে পারি?

foreach(T item in items)
{
    //...
}

itemsশূন্য কিনা তা নিয়ে চিন্তা না করেই ? ifঅবস্থা কি অতিমাত্রায়? অথবা এই উপর নির্ভর করে টাইপ এর itemsহয়তো বা Tপাশাপাশি?



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

উত্তর:


123

আপনাকে এখনও আইটেমগুলি পরীক্ষা করতে হবে (আইটেমগুলি = = নাল) অন্যথায় আপনি নালরফেরেন্সেক্সপশন পাবেন। তবে আপনি এই জাতীয় কিছু করতে পারেন:

List<string> items = null;  
foreach (var item in items ?? new List<string>())
{
    item.Dump();
}

তবে আপনি এটির কার্যকারিতা পরীক্ষা করতে পারেন। সুতরাং আমি এখনও (আইটেম! = নাল) আগে রাখা পছন্দ করি prefer

এরিকের লিপার্ট পরামর্শের ভিত্তিতে আমি কোডটি এতে পরিবর্তন করেছি:

List<string> items = null;  
foreach (var item in items ?? Enumerable.Empty<string>())
{
    item.Dump();
}

33
সুন্দর ধারণা; একটি খালি অ্যারে বেশি পছন্দনীয় কারণ এটি কম স্মৃতি গ্রহণ করে এবং কম মেমরির চাপ দেয়। অনুমিতযোগ্য mp কার্যকর <স্ট্রিং> আরও বেশি পছন্দনীয় হবে কারণ এটি খালি অ্যারেটিকে উত্পন্ন করে এটি পুনরায় ব্যবহার করে।
এরিক লিপার্ট

6
আমি আশা করি দ্বিতীয় কোডটি ধীর হবে। এটি এমন ক্রমের ক্রমটি IEnumerable<T>হ্রাস করে যা পুনরাবৃত্তিকে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে নাম দেয় interface আমার পরীক্ষাটি কোনও int অ্যারে ধরে পুনরাবৃত্তির জন্য 5 গুণক অবনতি দেখিয়েছে।
কোডসইনচওস

12
@ কোডইনচাউস: আপনি কি সাধারণত দেখতে পান যে একটি শূন্য ক্রম গণনার গতি আপনার প্রোগ্রামের পারফরম্যান্স বাধা?
এরিক লিপার্ট

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

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

77

সি # 6 ব্যবহার করে আপনি List<T>.ForEach(Action<T>)(বা আপনার নিজস্ব IEnumerable<T>.ForEachএক্সটেনশন পদ্ধতি) একসাথে নতুন নাল কন্ডিশনাল অপারেটরটি ব্যবহার করতে পারেন ।

List<string> items = null;
items?.ForEach(item =>
{
    // ...
});

মার্জিত উত্তর। ধন্যবাদ!
স্টিভ

4
এটি সর্বোত্তম সমাধান, কারণ এটি হয় না: ক) nullপুরো লুপটির Enumerable(সাধারণত ব্যবহারের ??সময়) এলসিডিতে সাধারণকরণের কর্মক্ষমতা অবনতি জড়িত , খ) প্রতিটি প্রকল্পে এক্সটেনশন পদ্ধতি যুক্ত করা প্রয়োজন, বা সি ) null IEnumerableএর সাথে (এফএফফ্ট! পুহ-লেইজ! এসএমএইচ।) এড়ানো প্রয়োজন (কোজ, nullমানে এন / এ, যেখানে খালি তালিকার অর্থ এটি অ্যাপ্লিকেশন। তবে বর্তমানে এটি ভাল, খালি ! অর্থাত্ একটি এমপিল) কমিশন থাকতে পারে যা অ-বিক্রয়ের জন্য এন / এ বা বিক্রয় যখন তারা কোন উপার্জন না করে খালি করে)।
টম

7
@ টম: এটি ধরে নিচ্ছে যে itemsকেবল কোনওটির List<T>চেয়ে বরং কিছুটা হলেও IEnumerable<T>। (বা একটি কাস্টম এক্সটেনশন পদ্ধতি রয়েছে, যা আপনি বলেছিলেন যে আপনি সেখানে থাকতে চান না ...) অতিরিক্তভাবে, আমি বলব যে 11 টি মন্তব্য যুক্ত করার পক্ষে এটি মূলত নয় যে সমস্তটি মূলত আপনাকে নির্দিষ্ট উত্তর পছন্দ করে বলেছে।
জন স্কিটি

4
@ টম: আমি আপনাকে ভবিষ্যতে এটি করতে দৃ strongly়ভাবে নিরুৎসাহিত করব। কল্পনা করুন যদি সবাই আপনার মন্তব্যের সাথে সহমত তারপর তাদের মন্তব্য জুড়েছে পুলিশের সব । (কল্পনা করুন যে আমি এখানে আমার উত্তরটি লিখেছি তবে 11 বার।) এটি স্ট্যাক ওভারফ্লোর কোনও উত্পাদনশীল ব্যবহার নয়।
জন স্কিটি

4
আমি আরও ধরে নিয়েছি যে কোনও মানসম্পন্ন বনামকে ডেকে ডেকে একটি পারফরম্যান্স হিট করব foreach। বিশেষত একটি তালিকার জন্য যা আমি মনে করি একটি forলুপে রূপান্তরিত হয় ।
kjbartel

38

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

যদি কোনও ক্রম কখনই বাতিল হয় না তবে স্পষ্টতই আপনার এটি পরীক্ষা করার দরকার নেই।


4
আপনি যদি ডাব্লুসিএফ পরিষেবা থেকে সিক্যুয়েন্স পান তবে কীভাবে? এটা নাল হতে পারে, তাই না?
নওয়াজ

4
@ নাওয়াজ: যদি আমার কাছে কোনও ডাব্লুসিএফ পরিষেবা থাকে যা আমাকে খালি অনুক্রমের উদ্দেশ্যে নাল সিকোয়েন্সগুলি ফিরিয়ে দেয় তবে আমি তাদের কাছে এটি বাগ হিসাবে জানাব। এটি বলেছিল: আপনার যদি তর্কযোগ্যভাবে বগি পরিষেবাগুলির খারাপভাবে গঠিত আউটপুট মোকাবেলা করতে হয় তবে হ্যাঁ, আপনাকে শূন্যতার জন্য পরীক্ষা করে এটি মোকাবেলা করতে হবে।
এরিক লিপার্ট

7
অবশ্যই, নাল এবং খালি মানে সম্পূর্ণ ভিন্ন জিনিস less কখনও কখনও এটি অনুক্রমের জন্য বৈধ।
Configurator

@ নাওয়াজ কীভাবে ডেটা টেবিল সম্পর্কে রয়েছে। রো যা খালি সংগ্রহের পরিবর্তে শূন্য দেয়। সম্ভবত এটি একটি বাগ?
নিল বি

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

10

আসলে যে @Connect উপর একটি বৈশিষ্ট্য অনুরোধ হল: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null

এবং প্রতিক্রিয়াটি বেশ যৌক্তিক:

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


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

6

আপনি সর্বদা নাল তালিকা দিয়ে এটি পরীক্ষা করে দেখতে পারতেন ... তবে এমএসডিএন ওয়েবসাইটে আমি এটি পেয়েছি

foreach-statement:
    foreach   (   type   identifier   in   expression   )   embedded-statement 

যদি এক্সপ্রেশনটির মান নাল থাকে তবে একটি সিস্টেম.নুলআরফরেন্সএক্সেপশন নিক্ষেপ করা হয়।


2

এটি অতিশয় নয়। রানটাইম আইটেমগুলিকে একটি আইনিম্যারেবলে কাস্ট করা হবে এবং এর গেটইনুমেটর পদ্ধতি কল করা হবে। এটি ব্যর্থ হবে এমন আইটেমগুলির একটি স্থিতিস্থাপকতার কারণ হবে


4
1) ক্রমটি অগত্যা কাস্ট করা হবে না IEnumerableএবং 2) এটি নিক্ষেপ করার সিদ্ধান্তের সিদ্ধান্ত। সি # সহজেই সেই nullচেকটি সন্নিবেশ করতে পারে যে বিকাশকারীরা এটি একটি ভাল ধারণা বলে মনে করে।
কোডসইনচওস

2

আপনি একটি এক্সটেনশান পদ্ধতিতে নাল চেকটি encapsulate এবং একটি ল্যাম্বডা ব্যবহার করতে পারেন:

public static class EnumerableExtensions {
  public static void ForEach<T>(this IEnumerable<T> self, Action<T> action) {
    if (self != null) {
      foreach (var element in self) {
        action(element);
      }
    }
  }
}

কোডটি হয়ে যায়:

items.ForEach(item => { 
  ...
});

যদি আপনি কেবল একটি আইটেম গ্রহণ করে এবং ফিরে আসে এমন কোনও পদ্ধতিতে কল করতে চান তবে আরও সংক্ষিপ্ত হতে পারে void:

items.ForEach(MethodThatTakesAnItem);

1

আপনার এই দরকার নেই foreachঅন্যথায় পুনরাবৃত্তি সেট আপ করতে ধারকটিতে প্রবেশ করলে আপনি একটি ব্যতিক্রম পাবেন ।

কভার অধীনে, foreachব্যবহার সংগ্রহে বর্গ উপর প্রয়োগ একটি ইন্টারফেস পুনরাবৃত্তির সঞ্চালন। জেনেরিক সমতুল্য ইন্টারফেস এখানে

সি # ভাষার পূর্বাভাস বিবৃতি (ভিজ্যুয়াল বেসিকের প্রতিটি জন্য) গণকের জটিলতা আড়াল করে। সুতরাং, গণনাকারীর সরাসরি কারসাজির পরিবর্তে ফোরচ ব্যবহার করার পরামর্শ দেওয়া হচ্ছে।


4
যেমন একটি নোট যেমন প্রযুক্তিগতভাবে ইন্টারফেসটি ব্যবহার করে না, তেমনি এটি হাঁসের টাইপিং ব্যবহার করে: ব্লগস.এমএসএনএন / বি / কেসিওয়ালিনা / অর্চিভ / ২০০7 /০ ////ducknotation.aspx ইন্টারফেসগুলি নিশ্চিত করে যে সঠিক পদ্ধতি এবং বৈশিষ্ট্য রয়েছে কিনা যদিও, এবং অভিপ্রায় সহায়তা বুঝতে। পাশাপাশি বাইরের
ফোরচ

0

পরীক্ষাটি প্রয়োজনীয়, কারণ যদি সংগ্রহটি শূন্য হয় তবে পূর্বাঞ্চ একটি নালরফেরান এক্সেক্সশন ফেলে দেবে। এটি চেষ্টা করে দেখার পক্ষে এটি বেশ সহজ।

List<string> items = null;
foreach(var item in items)
{
   Console.WriteLine(item);
}


0

এখানে উল্লিখিত হিসাবে আপনি পরীক্ষা করা উচিত এটি নাল নয়।

শূন্য করার জন্য মূল্যায়ন করে এমন কোনও অভিব্যক্তি ব্যবহার করবেন না।


0

সি # 6 এ আপনি এই জাতীয় লিখতে পারেন:

// some string from file or UI, i.e.:
// a) string s = "Hello, World!";
// b) string s = "";
// ...
var items = s?.Split(new char[] { ',', '!', ' ' }) ?? Enumerable.Empty<string>();  
foreach (var item in items)
{
    //..
}

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.