আইইনুমারেবলের জন্য কেন ফোরএচ এক্সটেনশন পদ্ধতি নেই?


389

নিখোঁজ Zipফাংশন সম্পর্কে জিজ্ঞাসা করে অন্য একটি প্রশ্ন দ্বারা অনুপ্রাণিত :

ক্লাসে কেন কোনও ForEachএক্সটেনশন পদ্ধতি নেই Enumerable? নাকি কোথাও? একমাত্র ক্লাস যে একটি ForEachপদ্ধতি পায় তা হ'ল List<>। এটি (কর্মক্ষমতা) অনুপস্থিত হওয়ার কোনও কারণ আছে কি?


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

2
'সরকারী উত্তর' থেকে লিঙ্ক সহ সংশ্লিষ্ট প্রশ্ন এখানে stackoverflow.com/questions/858978/...
Benjol

1
আরও দেখুন stackoverflow.com/questions/200574/...
goodeye

আমি মনে করি একটি খুব গুরুত্বপূর্ণ পয়েন্ট হ'ল, একটি foreach লুপ স্পট করা সহজ। আপনি যদি কোডটি দেখেন তবে .EEach (...) এটিকে সহজেই মিস করতে পারেন। এটি গুরুত্বপূর্ণ হয়ে ওঠে, যখন আপনার কার্য সম্পাদনের সমস্যা থাকে। অবশ্যই .ToList () এবং .ToArray () এর একই সমস্যা আছে তবে সেগুলি কিছুটা আলাদা ব্যবহৃত হয়। আর একটি কারণ হতে পারে এটি একটি সাধারণ ক্ষেত্রে। উত্স তালিকাকে সংশোধন করার জন্য প্রত্যেকটি (উপাদানগুলি অপসারণ / সংযোজন) যাতে এটি আর "খাঁটি" কোয়েরি না হয়।
ড্যানিয়েল বিয়ার 10

সমান্তরাল কোডটি ডিবাগ করার সময়, আমি প্রায়শই কেবলমাত্র পুনরায় আবিষ্কার করার Parallel.ForEachজন্য অদলবদল করার চেষ্টা করি যেটির Enumerable.ForEachউপস্থিতি নেই। সি # এখানে জিনিসগুলি সহজ করার জন্য একটি কৌশল মিস করেছেন।
কর্নেল আতঙ্ক

উত্তর:


198

ভাষাটির মধ্যে ইতিমধ্যে একটি ফোরচ স্টেটমেন্ট অন্তর্ভুক্ত রয়েছে যা বেশিরভাগ সময় কাজ করে।

আমি নিম্নলিখিত দেখতে ঘৃণা করব:

list.ForEach( item =>
{
    item.DoSomething();
} );

পরিবর্তে:

foreach(Item item in list)
{
     item.DoSomething();
}

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

তবে, আমাকে অবশ্যই স্বীকার করতে হবে যে আমি এই বিষয়ে আমার অবস্থান বদলেছি; একটি ForEach () এক্সটেনশন পদ্ধতি সত্যই কিছু পরিস্থিতিতে কার্যকর হবে।

বিবৃতি এবং পদ্ধতির মধ্যে এখানে প্রধান পার্থক্য রয়েছে:

  • টাইপ চেকিং: ফোরচ রানটাইম সময়ে করা হয়, ফরইচ () কম্পাইল সময় হয় (বিগ প্লাস!)
  • একটি প্রতিনিধি কল করার বাক্য গঠন প্রকৃতপক্ষে অনেক সহজ: অবজেক্টস.ফোর্চ (ডসোমথিং);
  • ফরইচ () শৃঙ্খলাবদ্ধ হতে পারে: যদিও এই জাতীয় বৈশিষ্ট্যের দুষ্টতা / উপযোগিতা আলোচনার জন্য উন্মুক্ত।

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


39
এখানে আলোচনার উত্তর দেয়: forums.microsoft.com/MSDN/… মূলত এই এক্সটেনশন পদ্ধতিগুলি "খাঁটি" রাখার সিদ্ধান্ত নেওয়া হয়েছিল to ফোরচ প্রতিটি এক্সটেনশন পদ্ধতিগুলি ব্যবহার করার সময় পার্শ্ব-প্রতিক্রিয়াগুলিকে উত্সাহিত করবে, যা উদ্দেশ্য ছিল না।
মানকাস

17
যদি আপনার সি ব্যাকগ্রাউন্ড থাকে তবে 'ফোরচ' আরও স্পষ্ট মনে হতে পারে তবে অভ্যন্তরীণ পুনরাবৃত্তি আপনার অভিপ্রায়টি আরও স্পষ্টভাবে জানিয়েছে। এর অর্থ আপনি 'সিকোয়েন্স.এএসপেনালাল ()। ফোরএচ (...)' এর মতো কাজ করতে পারেন।
জে বাজুজি

10
টাইপ চেকিং সম্পর্কে আপনার বক্তব্য সঠিক কিনা তা আমি নিশ্চিত নই। foreachসংকলনের সময়টি পরামিতিযুক্ত হয় কিনা তা সংকলনের সময় পরীক্ষা করা হয়। একটি অনুমানিক ForEachএক্সটেনশন পদ্ধতি হিসাবে এটিতে কেবল জেনেরিক অ সংগ্রহের জন্য সংকলন টাইম চেকিংয়ের অভাব রয়েছে ।
রিচার্ড পুল

49
এক্সটেনশন পদ্ধতি সত্যিই মত, বিন্দু স্বরলিপি সঙ্গে শৃঙ্খল LINQ মধ্যে উপযোগী হতে হবে: col.Where(...).OrderBy(...).ForEach(...)। অনেক সরল বাক্য গঠন, অপ্রয়োজনীয় স্থানীয় ভেরিয়েবল বা ফোর্যাচ () এর দীর্ঘ বন্ধনীগুলির সাথে কোনও পর্দা দূষণ নয়।
জেসেক গর্গোń

22
"আমি নিম্নলিখিতগুলি দেখতে ঘৃণা করি" - প্রশ্নটি আপনার ব্যক্তিগত পছন্দ সম্পর্কে নয় এবং আপনি বহিরাগত লাইনফিড এবং একটি বহির্মুখী বন্ধনী বন্ধনী যুক্ত করে কোডটিকে আরও ঘৃণ্য করেছিলেন। ঘৃণ্য হয় না list.ForEach(item => item.DoSomething())। এবং কে বলে এটি একটি তালিকা? সুস্পষ্ট ব্যবহারের ক্ষেত্রটি একটি শৃঙ্খলার শেষে; পূর্বাভাস বিবৃতিতে, আপনাকে পুরো চেইনটি পরে লাগাতে হবে inএবং ব্লকের অভ্যন্তরে অপারেশন করতে হবে যা প্রাকৃতিক বা সামঞ্জস্যপূর্ণ অনেক কম less
জিম বাল্টার

73

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

তবে, আপনি যদি সত্যিই এই ছোট্ট সুন্দর ফাংশনটি মিস করেন তবে আপনি নিজের সংস্করণটি রোল আউট করতে পারেন

public static void ForEach<T>(
    this IEnumerable<T> source,
    Action<T> action)
{
    foreach (T element in source) 
        action(element);
}

11
এক্সটেনশন পদ্ধতিগুলি এটির জন্য অনুমতি দেয়। যদি ইতিমধ্যে কোনও প্রদত্ত পদ্ধতির নামটির প্রয়োগকরণ থাকে তবে এক্সটেনশন পদ্ধতির পরিবর্তে সেই পদ্ধতিটি ব্যবহৃত হয়। সুতরাং আপনি ForEach এর একটি এক্সটেনশন পদ্ধতি বাস্তবায়িত করতে পারেন এবং এটি তালিকার <>> এর সাথে সংঘর্ষ না করে।
ক্যামেরন ম্যাকফারল্যান্ড

3
ক্যামেরন, বিশ্বাস করুন আমি জানি কীভাবে এক্সটেনশন পদ্ধতিগুলি কাজ করে :) তালিকাটি আনুমানিক হিসাবে উত্তরাধিকার সূত্রে আসে তাই এটি স্পষ্টত অসম্পূর্ণ জিনিস হবে।
আকু

9
এক্সটেনশন পদ্ধতিগুলি প্রোগ্রামিং গাইড ( এমএসডিএন.মাইক্রোসফট.ইন.উস / লিবারি / বিবি 383977.aspx ) থেকে: ইন্টারফেস বা শ্রেণি পদ্ধতি হিসাবে একই নাম এবং স্বাক্ষর সহ একটি এক্সটেনশন পদ্ধতি কখনই ডাকা হবে না। আমার কাছে বেশ সুস্পষ্ট মনে হচ্ছে।
ক্যামেরন ম্যাকফারল্যান্ড

3
আমি কি অন্য কিছু কথা বলছি? আমি মনে করি যখন অনেক ক্লাসে ফোরএচ পদ্ধতি থাকে তবে এর মধ্যে কিছু কিছু আলাদাভাবে কাজ করতে পারে।
আকু

5
তালিকা <> সম্পর্কে একটি আকর্ষণীয় বিষয় লক্ষণীয় For ফোরইচ এবং অ্যারে For তারা উভয় লুপের জন্য একটি সমতল ব্যবহার করে। হতে পারে এটি একটি পারফরম্যান্স জিনিস ( diditwith.net/2006/10/05/PerformanceOfForeachVsListForEach.aspx )। তবে এ অ্যারে এবং তালিকা উভয়ই ফরইচ পদ্ধতি প্রয়োগ করে, এটি আশ্চর্যজনক যে তারা কমপক্ষে আইলিস্ট <> এর জন্য একটি এক্সটেনশন পদ্ধতি বাস্তবায়ন করেনি, অবাক করা নয়, যদি আইইনামেবল <> নাও হয়।
ম্যাট ডটসন

53

আপনি এই এক্সটেনশন পদ্ধতিটি লিখতে পারেন:

// Possibly call this "Do"
IEnumerable<T> Apply<T> (this IEnumerable<T> source, Action<T> action)
{
    foreach (var e in source)
    {
        action(e);
        yield return e;
    }
}

পেশাদাররা

শৃঙ্খলার অনুমতি দেয়:

MySequence
    .Apply(...)
    .Apply(...)
    .Apply(...);

কনস

এটি পুনরাবৃত্তি বলপূর্বক কিছু না করা পর্যন্ত এটি আসলে কিছুই করবে না। যে কারণে, এটি কল করা উচিত নয় .ForEach()। আপনি .ToList()শেষে লিখতে পারেন , বা আপনি এই এক্সটেনশন পদ্ধতিটিও লিখতে পারেন:

// possibly call this "Realize"
IEnumerable<T> Done<T> (this IEnumerable<T> source)
{
    foreach (var e in source)
    {
        // do nothing
        ;
    }

    return source;
}

এটি শিপিং সি # লাইব্রেরি থেকে প্রস্থান খুব গুরুত্বপূর্ণ হতে পারে; আপনার এক্সটেনশন পদ্ধতির সাথে পরিচিত নয় এমন পাঠকরা আপনার কোডটি কী তৈরি করবেন তা জানেন না।


1
আপনার প্রথম ফাংশনটি 'উপলব্ধি' পদ্ধতিটি {foreach (var e in source) {action(e);} return source;}
ডাব্লু

3
আপনি কি আপনার প্রয়োগ পদ্ধতির পরিবর্তে কেবল নির্বাচন ব্যবহার করতে পারবেন না? আমার কাছে মনে হয় যে প্রতিটি উপাদানগুলিতে একটি ক্রিয়া প্রয়োগ করা এবং এটির ফলন হ'ল সিলেক্ট ঠিক তা করে। উদাহরণস্বরূপnumbers.Select(n => n*2);
রাসমুসভানসেন

1
আমি মনে করি প্রয়োগটি এই উদ্দেশ্যে সিলেক্ট করার চেয়ে বেশি পঠনযোগ্য। একটি নির্বাচনী বিবৃতি পড়ার সময়, আমি এটি "ভিতরে থেকে কিছু পান" হিসাবে প্রয়োগ করি যেখানে প্রয়োগ হিসাবে "কিছু কাজ করতে" হয়।
ডঃ রব ল্যাং

2
@rasmusvhansen আসলে, Select()প্রতিটি উপাদানকে একটি ফাংশন প্রয়োগ করুন এবং ফাংশনটির মান ফিরিয়ে দিন যেখানে প্রতিটি উপাদানকে Apply()একটি প্রয়োগ করুন Actionএবং মূল উপাদানটি ফিরিয়ে দিন বলে ।
নেটমেজ

1
এটি সমানSelect(e => { action(e); return e; })
জিম বাল্টার

35

এখানে আলোচনা উত্তর দেয়:

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

মূলত এই এক্সটেনশন পদ্ধতিগুলি কার্যকরভাবে "খাঁটি" রাখার সিদ্ধান্ত নেওয়া হয়েছিল। একটি ForEach পার্শ্ব প্রতিক্রিয়াগুলিকে উত্সাহিত করবে এনুমিনেবল এক্সটেনশন পদ্ধতিগুলি ব্যবহার করার সময়, যা উদ্দেশ্য ছিল না।


6
ব্লগস.এমএসএনএন / বি / অ্যারিক্লিপার্ট / অর্চিভ / ২০০৯/05/18/… দেখুন । ডিডিং এর ফলে ক্রিয়াকলাপের প্রোগ্রামিং নীতিগুলি লঙ্ঘন করে যে অন্যান্য সমস্ত সিকোয়েন্স অপারেটরগুলির উপর ভিত্তি করে। স্পষ্টতই এই পদ্ধতিতে কল করার একমাত্র উদ্দেশ্য পার্শ্ব প্রতিক্রিয়া সৃষ্টি করা
মাইকেল ফ্রেইজিম

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

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

17

যদিও আমি সম্মত হই যে foreachবেশিরভাগ ক্ষেত্রে অন্তর্নির্মিত কনস্ট্রাক্টটি ব্যবহার করা আরও ভাল , তবে আমি নিয়মিত foreachনিজেই সূচকটি পরিচালনা করার চেয়ে ফোরিচ <> এক্সটেনশনে এই প্রকরণটির ব্যবহারটি আরও সুন্দর বলে মনে করি:

public static int ForEach<T>(this IEnumerable<T> list, Action<int, T> action)
{
    if (action == null) throw new ArgumentNullException("action");

    var index = 0;

    foreach (var elem in list)
        action(index++, elem);

    return index;
}
উদাহরণ
var people = new[] { "Moe", "Curly", "Larry" };
people.ForEach((i, p) => Console.WriteLine("Person #{0} is {1}", i, p));

আপনাকে দেবে:

Person #0 is Moe
Person #1 is Curly
Person #2 is Larry

দুর্দান্ত এক্সটেনশন, তবে আপনি কি কিছু ডকুমেন্টেশন যুক্ত করতে পারেন? প্রত্যাশিত মূল্যের ব্যবহারটি কী? কেন সূচকটি নির্দিষ্টভাবে কোনও ইন্টের চেয়ে আলাদা? নমুনা ব্যবহার?
চিহ্নিত করুন

চিহ্ন: প্রত্যাবর্তনের মান হল তালিকার উপাদানগুলির সংখ্যা। ইনডেক্স হয় বিশেষভাবে, কোন int হিসাবে টাইপ করা অন্তর্নিহিত টাইপিং ধন্যবাদ।
ক্রিস জুইরিক

@ ক্রিস, উপরের আপনার কোডের উপর ভিত্তি করে, রিটার্ন মান তালিকার শেষ মানটির শূন্য-ভিত্তিক সূচক, তালিকার উপাদানগুলির সংখ্যা নয়।
এরিক স্মিথ

@ ক্রিস, এটি নেই: মান গ্রহণের পরে সূচকটি বৃদ্ধি করা হয় (পোস্টফিক্স ইনক্রিমেন্ট), সুতরাং প্রথম উপাদানটি প্রক্রিয়া করার পরে সূচকটি 1 হবে এবং আরও কিছু হবে। সুতরাং রিটার্ন মান আসলে উপাদান গণনা।
মার্টিনস্টেটনার

1
@ মার্টিনস্টটনার এরিক স্মিথের 5/16-এর মন্তব্যটি পূর্ববর্তী সংস্করণ থেকে এসেছে। তিনি সঠিক মান ফেরত দেওয়ার জন্য 5/18 কোডটি সংশোধন করেছিলেন।
মাইকেল ব্ল্যাকবার্ন

16

একটি কর্মপরিকল্পনা লিখতে হয় .ToList().ForEach(x => ...)

অনুকূল

বুঝতে সহজ - পাঠককে কেবল সি # দিয়ে কী কী জাহাজগুলি বোঝানো প্রয়োজন, কোনও অতিরিক্ত এক্সটেনশন পদ্ধতি নয়।

সিনট্যাকটিক গোলমাল খুব হালকা (কেবলমাত্র কিছু অযৌক্তিক কোড যুক্ত করা হয়)।

সাধারণত অতিরিক্ত মেমোরির জন্য খরচ হয় না, যেহেতু .ForEach()কোনও নেটিভকে পুরো সংগ্রহটি উপলব্ধি করতে হবে।

কনস

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

তালিকাটি উপলব্ধি করে যদি একটি ব্যতিক্রম ছুঁড়ে ফেলা হয় তবে আপনি কখনই কোনও একক উপাদানের সাথে কাজ করতে পারবেন না।

যদি গণনা অসীম হয় (প্রাকৃতিক সংখ্যার মতো), আপনি ভাগ্য থেকে দূরে।


1
ক) এটি দূরবর্তী অবস্থান থেকে প্রশ্নের উত্তরও নয়। খ) এই প্রতিক্রিয়াটি আরও পরিষ্কার হবে যদি এটি সামনে উল্লিখিত থাকে যে কোনও Enumerable.ForEach<T>পদ্ধতি না থাকলেও একটি List<T>.ForEachপদ্ধতি রয়েছে। গ) "একটি আদিবাসী হওয়ায় সাধারণত অতিরিক্ত মেমোরির জন্য খরচ হয় না For কারণ প্রতিটি () যাইহোক, পুরো সংগ্রহটি অনুধাবন করতে হবে।" - সম্পূর্ণ এবং সম্পূর্ণ বাজে কথা। এখানে গণ্যমানের বাস্তবায়ন রয়েছে Forফের জন্য প্রতিটি <T> সি # যদি এটি করত তবে তা প্রদান করবে:public static void ForEach<T>(this IEnumerable<T> list, Action<T> action) { foreach (T item in list) action(item); }
জিম বাল্টার

13

আমি সবসময়ই ভাবতাম যে আমি নিজেই, তাই আমি সবসময় আমার সাথে এটি রাখি:

public static void ForEach<T>(this IEnumerable<T> col, Action<T> action)
{
    if (action == null)
    {
        throw new ArgumentNullException("action");
    }
    foreach (var item in col)
    {
        action(item);
    }
}

দুর্দান্ত সামান্য এক্সটেনশন পদ্ধতি।


2
কর্ন নাল হতে পারে ... আপনি এটি পরীক্ষা করতে পারেন।
অ্যামি বি

হ্যাঁ আমি আমার লাইব্রেরিতে চেক করি, সেখানে এটি দ্রুত করার সময় আমি এটি মিস করেছি।
অ্যারন পাওয়েল

আমি এটি আকর্ষণীয় মনে করি যে প্রত্যেকে শূন্যের জন্য অ্যাকশন প্যারামিটারটি পরীক্ষা করে তবে উত্স / করল প্যারামিটারটি কখনও নয়।
ক্যামেরন ম্যাকফারল্যান্ড

2
আমি এটি আকর্ষণীয় মনে করি যে প্রত্যেকে নাল জন্য পরামিতিগুলি পরীক্ষা করে, যখন কোনও ব্যতিক্রমের ফলাফলগুলি পরীক্ষা না করে ...

একদমই না. একটি নাল রেফার ব্যতিক্রম আপনাকে যে পরামিতিটির ত্রুটি ছিল তার নামটি বলবে না। এবং আপনি লুপটিও পরীক্ষা করতে পারেন যাতে আপনি একটি নির্দিষ্ট নল রেফকে ফেলে দিতে পারেন বলে [সূচী #] একই কারণে শূন্য ছিল
রজার উইলককস

8

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

লিনকিউ এক্সটেনশন পদ্ধতিগুলি সমস্ত মান দেয় যাতে তারা এক সাথে বেঁধে রাখা যায়:

collection.Where(i => i.Name = "hello").Select(i => i.FullName);

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

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


7

আপনি Selectপ্রথমে আপনার ক্রিয়াকলাপটি করে, এবং তারপরে পরিচয় ফিরিয়ে ((আপনি যদি চান তবে অন্য কিছু )) ব্যবহার করতে পারেন (শৃঙ্খলাবদ্ধ, তবে অলসভাবে মূল্যায়ন করা) use

IEnumerable<string> people = new List<string>(){"alica", "bob", "john", "pete"};
people.Select(p => { Console.WriteLine(p); return p; });

আপনার অবশ্যই তা নিশ্চিত করা দরকার যে এটি এখনও মূল্যায়ন করা হয়, হয় হয় হয় Count()(আফাইক গণনার সস্তারতম অপারেশন) বা অন্য যে কোনও অপারেশন আপনাকে যেভাবেই প্রয়োজন।

আমি এটি স্ট্যান্ডার্ড লাইব্রেরিতে আনা দেখতে দেখতে চাই তবে:

static IEnumerable<T> WithLazySideEffect(this IEnumerable<T> src, Action<T> action) {
  return src.Select(i => { action(i); return i; } );
}

উপরের কোডটি তখন হয়ে যায় people.WithLazySideEffect(p => Console.WriteLine(p))যা কার্যকরভাবে পূর্বাভাসের সমান, তবে অলস এবং শৃঙ্খলাবদ্ধ।


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

@ অ্যালেক্সকি স্মিথ আপনি যদি সি # এর পূর্বেভাগের মতো সিকোয়েন্স অপারেটর রাখেন তবে আপনি এক্সপ্রেশন সিনট্যাক্স দিয়ে এটি করতে পারেন। তবে ফরইচের পুরো বিষয়টি হ'ল এটি শূন্য প্রকারের সাথে পদক্ষেপ নেয় এবং আপনি সি # তে প্রকাশের ক্ষেত্রে শূন্য প্রকারগুলি ব্যবহার করতে পারবেন না।
জিম বাল্টার

ইমো, এখন যা করা Selectউচিত হবে তা আর করে না। এটি অবশ্যই ওপি যা যা চায় তার একটি সমাধান - তবে পাঠ্যযোগ্যতার বিষয়: কেউই প্রত্যাশা করতে পারে না যে নির্বাচিত কোনও ফাংশন সম্পাদন করে।
ম্যাথিয়াস বার্গার

@ ম্যাথিয়াসবার্গার যদি Selectএটি করার কথা বলে না তবে এটি বাস্তবায়ন করতে সমস্যা Select, কোডটি কল করে না Select, যা করার উপর কোনও প্রভাব Selectনেই।
মার্টিজন


4

@Coincoin

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

Action<blah,blah> f = { foo };

List1.ForEach(p => f(p))
List2.ForEach(p => f(p))

ইত্যাদি ...

যুক্তিটি এক জায়গায় এবং আপনি নিজের শ্রেণিকে কলুষিত করেন নি।


foreach (List1.Concat মধ্যে Var P (List2) .Concat (তালিকা 3)) {... কাপড় না ...}
ক্যামেরন MacFarland

যদি হিসাবে সহজ হিসাবে f(p), তারপর ছেড়ে { }জন্য সাধারণভাবে সংক্ষেপে: for (var p in List1.Concat(List2).Concat(List2)) f(p);
স্পোলসন

3

বেশিরভাগ লিনকিউ এক্সটেনশন পদ্ধতিতে ফলাফল ফিরে আসে। ForEach এই প্যাটার্নে খাপ খায় না কারণ এটি কিছুই দেয় না।


2
ফরইচ অ্যাকশন <T> ব্যবহার করে যা ডেলিগেটের অন্য রূপ
অ্যারন পাওয়েল

2
লেপির ডান বাদে, সমস্ত প্রকারের এক্সটেনশান পদ্ধতিগুলি একটি মান ফেরত দেয়, সুতরাং ফোরইচ এই প্যাটার্নটি ফিট করে না। প্রতিনিধিরা এর মধ্যে আসে না।
ক্যামেরন ম্যাকফারল্যান্ড

যেহেতু কোনও এক্সটেনশান পদ্ধতিতে কোনও ফলাফল ফিরে আসতে হয় না, এটি প্রায়শই ব্যবহৃত অপারেশনটি কল করার উপায় যুক্ত করার উদ্দেশ্যে কাজ করে
অ্যারন পাওয়েল

1
আসলে, স্লেস। সুতরাং এটি যদি একটি মান ফেরত না?
ট্রমাপনি

1
@ মার্তিজান অর্থাত্public IEnumerable<T> Foreach<T>(this IEnumerable<T> items, Action<T> action) { /* error check */ foreach (var item in items) { action(item); yield return item; } }
ম্যাককে

3

আপনার যদি F # থাকে (যা .NET এর পরবর্তী সংস্করণে থাকবে), আপনি ব্যবহার করতে পারেন

Seq.iter doSomething myIEnumerable


9
সুতরাং মাইক্রোসফ্ট সি # এবং ভিবিতে আইনামিউরেবলের জন্য একটি ফরইচ পদ্ধতি সরবরাহ না করা বেছে নিয়েছে, কারণ এটি নিখুঁতভাবে কার্যকরী হবে না; তবুও তারা তাদের আরও কার্যকরী ভাষায় এফ (নামকরণ করে) সরবরাহ করে। তাদের যুক্তি আমাকে আভাস দেয়।
স্কট হাচিনসন

3

আংশিকভাবে এটি এর কারণ ভাষা ডিজাইনারগণ দার্শনিক দৃষ্টিকোণ থেকে এটির সাথে একমত নন।

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

https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/


2

আপনি যখন কিছু ফিরিয়ে দিতে চান তখন আপনি নির্বাচন নির্বাচন করতে পারেন। আপনি যদি তা না করেন তবে আপনি প্রথমে টোললিস্ট ব্যবহার করতে পারেন, কারণ আপনি সম্ভবত সংগ্রহে কোনও কিছু পরিবর্তন করতে চান না।


ক) এটি প্রশ্নের উত্তর নয়। খ) টোললিস্টে অতিরিক্ত সময় এবং স্মৃতি দরকার।
জিম বাল্টার

2

আমি এটি সম্পর্কে একটি ব্লগ পোস্ট লিখেছি: http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx

আপনি এই পদ্ধতিটি .NET 4.0: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=279093 এ দেখতে চাইলে আপনি এখানে ভোট দিতে পারেন


এটি কি কখনও বাস্তবায়িত হয়েছিল? আমি কল্পনা করি না, তবে এই টিকিটের পরিবর্তে অন্য কোনও ইউআরএল আছে কি? এমএস সংযোগ বন্ধ হয়ে গেছে
6:55

এটি কার্যকর করা হয়নি। Github.com/dotnet/runtime/issues
কিরিল ওসেনকোভ

2

৩.৩-এ, আইইনিউমারেবলের সাথে যুক্ত সমস্ত এক্সটেনশন পদ্ধতিগুলি লিনকিউ সহায়তার জন্য রয়েছে (লক্ষ্য করুন যে সেগুলি সিস্টেমের মধ্যে সংজ্ঞায়িত করা হয়েছে in এই পোস্টে, আমি ব্যাখ্যা করছি কেন ফোরচ লিনকিউ-তে অন্তর্ভুক্ত নয়: বিদ্যমান লিনকিউ এক্সটেনশন পদ্ধতি সমান্তরাল.ফোর?


2

এটি কি আমি বা তালিকাটি <T> ore মূলত সেখানে ছিল

foreach(X x in Y) 

যেখানে ওয়াইয়ের জন্য সহজেই আইনুমেবল (প্রাক 2.0) হওয়া উচিত এবং একটি getEnumerator () প্রয়োগ করতে হবে। উত্পন্ন এমএসআইএলটির দিকে নজর দিলে আপনি দেখতে পাচ্ছেন যে এটি ঠিক একই রকম

IEnumerator<int> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
    int i = enumerator.Current;

    Console.WriteLine(i);
}

( এমএসআইএল-এর জন্য http://alski.net/post/0a-for-foreach-forFrest-forLast0a-0a-.aspx দেখুন )

তারপরে ডটনেট ২.০ এ জেনেরিক্স এবং তালিকাটি এসেছিল। ফরচ আমাকে সবসময় ভিসর প্যাটার্নের একটি বাস্তবায়ন বলে মনে করেছে, (গামা, হেলম, জনসন, ভ্লিসাইডস ডিজাইন প্যাটার্নস দেখুন)।

এখন অবশ্যই ৩.৫ এ আমরা একই পরিবর্তে ল্যাম্বদা ব্যবহার করতে পারি, উদাহরণস্বরূপ http://dotnet-developments.blogs.techtarget.com/2008/09/02/iterators-lambda-and-linq-oh- আমার/


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

2

আমি আকুর উত্তরটি প্রসারিত করতে চাই ।

আপনি যদি পুরো গণনাকারীটিকে পূর্বে না ঘটাতে পার্শ্ব-প্রতিক্রিয়ার একমাত্র উদ্দেশ্যে কোনও পদ্ধতিতে কল করতে চান তবে আপনি এটি ব্যবহার করতে পারেন:

private static IEnumerable<T> ForEach<T>(IEnumerable<T> xs, Action<T> f) {
    foreach (var x in xs) {
        f(x); yield return x;
    }
}

1
এটি একইSelect(x => { f(x); return x;})
জিম বাল্টার

0

কেউ এখনও চিহ্নিত করতে পারেনি যে ফরইচ <টি> ফলক কীওয়ার্ড রানটাইম চেক করা আছে যেখানে সংকলন টাইম চেকিংয়ের ফলাফল।

কোডটিতে উভয় পদ্ধতিই ব্যবহৃত হয়েছিল এমন কিছু রিফ্যাক্টরিং করে, আমি পক্ষপাতিত্ব করি For


5
আসলেই কি এই ঘটনা? foreachকোন কম কম্পাইল সময় পরীক্ষা করা আছে তা দেখতে আমি ব্যর্থ । অবশ্যই, যদি আপনার সংগ্রহটি একটি জেনারিক আইমনামেবল হয় তবে লুপ ভেরিয়েবলটি একটি হবে তবে অনুমানিক এক্সটেনশন পদ্ধতির ক্ষেত্রে objectএটি একই হবে ForEach
রিচার্ড পুল

1
এটি গৃহীত উত্তরে উল্লেখ করা হয়েছে। তবে এটি কেবল ভুল (এবং উপরে রিচার্ড পুল সঠিক)।
জিম বাল্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.