একটি সংগ্রহে AddRange


109

একজন সহকর্মী আমাকে আজ জিজ্ঞাসা করলেন কীভাবে কোনও সংকলনে একটি ব্যাপ্তি যুক্ত করতে হয়। তার একটি বর্গ রয়েছে যা থেকে উত্তরাধিকার সূত্রে প্রাপ্ত Collection<T>। ইতিমধ্যে কিছু আইটেম রয়েছে যে ধরণের একটি প্রাপ্য সম্পত্তি আছে। তিনি অন্য সংগ্রহের আইটেমগুলি সম্পত্তি সংগ্রহের সাথে যুক্ত করতে চান। তিনি কীভাবে সি # 3- বান্ধব ফ্যাশনে এটি করতে পারেন? (কেবলমাত্র প্রাপ্ত সম্পত্তি সম্পর্কে সীমাবদ্ধতাটি লক্ষ্য করুন, যা ইউনিয়ন করা এবং পুনরায় নিয়োগের মতো সমাধানগুলি প্রতিরোধ করে))

অবশ্যই, সম্পত্তি সঙ্গে একটি ভবিষ্যদ্বাণী। অ্যাড কাজ করবে। তবে একটি List<T>স্টাইলের অ্যাড্রেঞ্জ আরও বেশি মার্জিত হবে।

এটি একটি এক্সটেনশন পদ্ধতি লিখতে যথেষ্ট সহজ:

public static class CollectionHelpers
{
    public static void AddRange<T>(this ICollection<T> destination,
                                   IEnumerable<T> source)
    {
        foreach (T item in source)
        {
            destination.Add(item);
        }
    }
}

তবে আমার অনুভূতি আছে যে আমি চাকাটি নতুন করে আনছি। আমি কিছুই অনুরূপ খুঁজে পাইনি System.Linqবা morelinq

খারাপ ডিজাইন? শুধু কল অ্যাড? সুস্পষ্ট অনুপস্থিত?


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

একটি সমস্যা, ICollection<T>একটি Addপদ্ধতি আছে বলে মনে হয় না । msdn.microsoft.com/en-us/library/… তবে Collection<T>একটি আছে।
টিম গুডম্যান

@ টিম গুডম্যান - এটি নন-জেনেরিক ইন্টারফেস। দেখুন msdn.microsoft.com/en-us/library/92t2ye13.aspx
TrueWill

"বিদ্যমান সংগ্রহগুলি সংশোধন করা সত্যিই লিনকিউ-এর উদ্দিষ্ট উদ্দেশ্যগুলির ক্ষেত্রের মধ্যে পড়ে না"। @ লেভি তবে কেন Add(T item)প্রথম স্থান অধিকার করেছেন? একটি একক আইটেম যুক্ত করার সক্ষমতা প্রদানের জন্য অর্ধ-বেকড পদ্ধতির মতো মনে হচ্ছে এবং তারপরে একবারে একাধিক সংখ্যক যোগ করার জন্য সমস্ত কলার পুনরাবৃত্তি করবে। আপনার বক্তব্য অবশ্যই সত্য IEnumerable<T>তবে আমি ICollectionsএকাধিক অনুষ্ঠানে নিজেকে হতাশ পেয়েছি । আমি তোমার সাথে একমত নই, শুধু বেরোচ্ছে।
আকস্মাতা

উত্তর:


62

না, এটি পুরোপুরি যুক্তিসঙ্গত বলে মনে হচ্ছে। একটি List<T>.অ্যাড্রেঞ্জ () পদ্ধতি রয়েছে যা মূলত এটি করে তবে আপনার সংগ্রহটি কংক্রিটের প্রয়োজন List<T>


1
ধন্যবাদ; খুব সত্য, তবে বেশিরভাগ সরকারী সম্পত্তিগুলি এমএস নির্দেশিকাগুলি অনুসরণ করে এবং তালিকাভুক্ত হয় না।
ট্রুউইল

7
হ্যাঁ - কেন আমি মনে করি না যে এটি করার ক্ষেত্রে কোনও সমস্যা আছে for কেবল উপলব্ধি করুন যে এটি তালিকা <টি> সংস্করণের চেয়ে কম দক্ষ হবে (যেহেতু তালিকাটি <T> প্রাক বরাদ্দ করতে পারে)
রিড কোপসি

NET কোর ২.২ এ অ্যাডরেঞ্জ পদ্ধতিটি কেবল এই সাবধানে দেখানো হয়েছে যে, ভুলভাবে ব্যবহার করা হলে একটি অদ্ভুত আচরণ দেখাতে পারে তা কেবল যত্ন নিন: github.com/dotnet/core/issues/2667
ব্রুনো

36

লুপ চালানোর আগে এক্সটেনশন পদ্ধতিতে তালিকায় কাস্ট করার চেষ্টা করুন। এইভাবে আপনি তালিকা.এডড্রেঞ্জের পারফরম্যান্সের সুবিধা নিতে পারেন।

public static void AddRange<T>(this ICollection<T> destination,
                               IEnumerable<T> source)
{
    List<T> list = destination as List<T>;

    if (list != null)
    {
        list.AddRange(source);
    }
    else
    {
        foreach (T item in source)
        {
            destination.Add(item);
        }
    }
}

2
asঅপারেটর নিক্ষেপ করবে না। যদি destinationcastালাই করা না যায় listতবে তা বাতিল হয়ে যাবে এবং elseব্লকটি কার্যকর হবে।
rymdsmurf

4
arrgggh! পবিত্র যে সমস্ত ভালবাসার জন্য শর্ত শাখা অদলবদল!
নিকোডেমাস 13

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

13
"কিছু! = নাল" ব্যাখ্যা করা "কিছু == নাল" ব্যাখ্যা করার চেয়ে বেশি কঠিন নয়। অস্বীকৃতি অপারেটর তবে একটি সম্পূর্ণ ভিন্ন জিনিস, এবং যদি 'অন্য-বিবৃতি rewriting হবে আপনার শেষ উদাহরণে elliminate যে অপারেটর। এটি উদ্দেশ্যমূলকভাবে একটি উন্নতি, তবে এটি মূল প্রশ্নের সাথে সম্পর্কিত নয়। সেই বিশেষ ক্ষেত্রে দুটি ফর্মটি ব্যক্তিগত পছন্দের বিষয় এবং উপরের যুক্তি অনুসারে আমি "! =" - অপারেটরটিকে পছন্দ করব।
rymdsmurf

15
প্যাটার্ন মেলানো প্রত্যেককে আনন্দিত করবে ... ;-)if (destination is List<T> list)
জ্যাকব ফশি ১৯

28

যেহেতু .NET4.5আপনি যদি ওয়ান-লাইনার চান তবে আপনি ফোরইচ ব্যবহার করতে পারেন System.Collections.Generic

source.ForEach(o => destination.Add(o));

এমনকি ছোট হিসাবে

source.ForEach(destination.Add);

পারফরম্যান্স-ভিত্তিতে এটি প্রতিটি লুপের মতো (সিনট্যাকটিক চিনি)।

এছাড়াও না মত বরাদ্দ চেষ্টা

var x = source.ForEach(destination.Add) 

কারণ ForEachঅকার্যকর।

সম্পাদনা করুন: মন্তব্য থেকে অনুলিপি করা হয়েছে, ফ্রিচ-এ লিপার্টের মতামত


9
ব্যক্তিগতভাবে আমি এই একের সাথে লিপার্টের সাথে আছি: ব্লগস.এমএসডিএন
আর্কিলিপার্ট

1
এটি উত্স হওয়া উচিত? ForEach (গন্তব্য.আড্ড)?
ফ্রাঙ্ক

4
ForEachমনে হয় কেবল সংজ্ঞায়িত হয়েছে List<T>, না Collection?
রক্ষক এক


এরিক লিপার্টের ব্লগ পোস্টে আপডেট হওয়া লিঙ্ক: কোডিংয়ে চমত্কার অ্যাডভেঞ্চার "ফরচ" বনাম "ফোরএচ"
আলেকজান্ডার

19

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


3
এটি যুক্ত করার জন্য, অ্যাডরেঞ্জের সাথে একটি বাল্ক বিজ্ঞপ্তির বিপরীতে প্রতিটি সংযোজনের জন্য সংগ্রহ পরিবর্তন বিজ্ঞপ্তিও থাকবে।
নিক উডেল

3

এখানে কিছুটা আরও উন্নত / উত্পাদনের জন্য প্রস্তুত সংস্করণ রয়েছে:

    public static class CollectionExtensions
    {
        public static TCol AddRange<TCol, TItem>(this TCol destination, IEnumerable<TItem> source)
            where TCol : ICollection<TItem>
        {
            if(destination == null) throw new ArgumentNullException(nameof(destination));
            if(source == null) throw new ArgumentNullException(nameof(source));

            // don't cast to IList to prevent recursion
            if (destination is List<TItem> list)
            {
                list.AddRange(source);
                return destination;
            }

            foreach (var item in source)
            {
                destination.Add(item);
            }

            return destination;
        }
    }

জিমস্মার্ফের উত্তর নিখরচায় দেখতে খুব সহজ, তবে এটি ভিন্ন ভিন্ন লিস্টের সাথে কাজ করে। এই কোডটিকে এই ব্যবহারের ক্ষেত্রে সমর্থন করা কি সম্ভব?
রিচার্ডসনআউটআর

উদাহরণস্বরূপ: একটি বিমূর্ত শ্রেণীর destinationএকটি তালিকা Shapesourceএকটি তালিকা রয়েছে Circle, একটি উত্তরাধিকারসূত্রে বর্গ।
রিচার্ডসনআউটআর

1

, C5 জেনেরিক সংগ্রহগুলি লাইব্রেরী শ্রেণীর সব সমর্থন AddRangeপদ্ধতি। সি 5 এর আরও অনেক দৃust় ইন্টারফেস রয়েছে যা প্রকৃতপক্ষে এর অন্তর্নিহিত বাস্তবায়নগুলির সমস্ত বৈশিষ্ট্যই প্রকাশ করে System.Collections.Generic ICollectionএবং IListইন্টারফেসের সাথে এবং ইন্টারফেসের সাথে সামঞ্জস্যপূর্ণ , যার অর্থ C5সংগ্রহগুলি সহজেই অন্তর্নিহিত বাস্তবায়ন হিসাবে প্রতিস্থাপিত হতে পারে।


0

আপনি কোনও তালিকাতে আপনার মূল সংখ্যাটি যুক্ত করতে পারেন তারপরে তালিকায় আইকোলিকেশন = সেট করুন।

        IEnumerable<T> source;

        List<item> list = new List<item>();
        list.AddRange(source);

        ICollection<item> destination = list;

3
এটি কার্যত কার্যকরভাবে কাজ করার সময়, এটি সংগ্রহের বৈশিষ্ট্যগুলি কেবলমাত্র পড়ার জন্য মাইক্রোসফ্টের নির্দেশিকা ভঙ্গ করে ( msdn.microsoft.com/en-us/library/ms182327.aspx )
নিক উডেল

0

অথবা আপনি এই জাতীয় আইকোলিকেশন এক্সটেনশনটি কেবল তৈরি করতে পারেন:

 public static ICollection<T> AddRange<T>(this ICollection<T> @this, IEnumerable<T> items)
    {
        foreach(var item in items)
        {
            @this.Add(item);
        }

        return @this;
    }

এটি ব্যবহারের তালিকায় এটি ব্যবহার করার মতো হবে:

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