একটি IEnumerable <T> থেকে একটি আইকোলিকেশন <T> তে রূপান্তর করা যায় না


91

আমি নিম্নলিখিতটি সংজ্ঞায়িত করেছি:

public ICollection<Item> Items { get; set; }

যখন আমি এই কোডটি চালাই:

Items = _item.Get("001");

আমি নিম্নলিখিত বার্তাটি পেয়েছি:

Error   3   
Cannot implicitly convert type 
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to 
'System.Collections.Generic.ICollection<Storage.Models.Item>'. 
An explicit conversion exists (are you missing a cast?)

আমি কী ভুল করছি তা কেউ ব্যাখ্যা করতে পারেন। আমি অনুমিত, সংগ্রহ এবং টোললিস্ট () ব্যবহারের মধ্যে পার্থক্য সম্পর্কে খুব বিভ্রান্ত

যুক্ত তথ্য

পরে আমার কোডে আমার নিম্নলিখিতগুলি রয়েছে:

for (var index = 0; index < Items.Count(); index++) 

আইটেমগুলিকে একটি আইনুমেয়রিয়াল হিসাবে সংজ্ঞায়িত করতে আমি কি ঠিক আছি?


4
আপনি _item এর ধরণ এবং get (স্ট্রিং) এর স্বাক্ষর (বিশেষত রিটার্ন টাইপ) সম্পর্কে আরও তথ্য সরবরাহ করতে পারেন?
— ডাঃ অ্যান্ড্রু বার্নেট-থম্পসন

এ জাতীয় ধরণ বদলাবে না কেন? public IEnumerable<Item> Items { get; set; }আপনার কাছে এটি থাকার কোনও বিশেষ কারণ আছে ICollection?
— শ্যাডো উইজার্ড আপনার জন্য

অনুমানযোগ্য <টি> পান (স্ট্রিং পিকে);
— সামান্থা জেটি স্টার

উত্তর:


113

ICollection<T>IEnumerable<T>এর ফলাফল নির্ধারণের জন্য উত্তরাধিকারসূত্রে

IEnumerable<T> Get(string pk)

একটি থেকে ICollection<T>সেখানে দুটি উপায় আছে।

// 1. You know that the referenced object implements `ICollection<T>`,
//    so you can use a cast
ICollection<T> c = (ICollection<T>)Get("pk");

// 2. The returned object can be any `IEnumerable<T>`, so you need to 
//    enumerate it and put it into something implementing `ICollection<T>`. 
//    The easiest is to use `ToList()`:
ICollection<T> c = Get("pk").ToList();

দ্বিতীয় বিকল্পগুলি আরও নমনীয়, তবে এর কার্যকারিতা অনেক বেশি। আরেকটি বিকল্প হ'ল ফল হিসাবে সংরক্ষণ করা IEnumerable<T>যদি না আপনার ICollection<T>ইন্টারফেসের সাহায্যে অতিরিক্ত কার্যকারিতা প্রয়োজন হয় ।

অতিরিক্ত পারফরম্যান্স মন্তব্য

আপনার কাছে লুপ আছে

for (var index = 0; index < Items.Count(); index++)

কাজ করে IEnumerable<T>তবে এটি অদক্ষ; প্রতিটি কলটিতে সমস্ত উপাদানগুলির Count()একটি সম্পূর্ণ গণনা প্রয়োজন । হয় সংগ্রহ এবং Countসম্পত্তি ব্যবহার করুন (প্রথম বন্ধনী ব্যতীত) বা এটিকে ফোরচ লুপে রূপান্তর করুন:

foreach(var item in Items)

4
আইকোলিকেশন দ্বারা যুক্ত অতিরিক্ত কার্যকারিতা কী?
— সামান্থা জেটি স্টার

7
ICollection<T>ম্যানিপুলেট করা যেতে পারে ( বিশদটির জন্য ডকটি দেখুন), যখন একটি IEnumerable<T>কেবল গণনা করা যায়।
— অ্যান্ডারস আবেল

আমার এমন কিছু থাকা দরকার যেখানে আমি বিভিন্ন লিনকুই ক্যোয়ারি চালাতে পারি। আমাকে তালিকায় এ জাতীয় কিছু যুক্ত করার বা করার দরকার নেই। তার মানে কি আমি আইকোলিকেশন দিয়ে আরও ভাল থাকব।
— সামান্থা জেটি স্টার

LINQ উপর কাজ করে IEnumerable<T>তাই IEnumerable<T>যে ক্ষেত্রে যথেষ্ট।
— এন্ডারস আবেল

31

আপনি সরাসরি থেকে রূপান্তর করতে পারবেন না IEnumerable<T>করার ICollection<T>। আপনি এটিকে রূপান্তর করার ToListপদ্ধতিটি ব্যবহার করতে পারেনIEnumerable<T>ICollection<T>

someICollection = SomeIEnumerable.ToList();


এটি আমার পক্ষে কাজ করে। তবে কি রূপান্তর করা আমার পক্ষে ভাল ধারণা বা আইটেমগুলির ধরণ হিসাবে আইনিউনামেবল ব্যবহার করা ভাল। আমি যদি ব্যবহারযোগ্য হয় তবে আমি কি এটি তৈরি করছি যাতে আমার প্রোগ্রামে পরে যদি প্রয়োজন হয় তবে আমি আইটেমগুলিতে আরও ক্রিয়া করতে পারি?
— সামান্থা জেটি স্টার

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

আমি টোললিস্ট () ব্যবহার করলে আমার কী কী সুবিধা হবে তা বোঝার চেষ্টা করছি। আমার কাছে ডেটা হয়ে গেলে আমি আইটেমগুলির বিরুদ্ধে লিনকুই ক্যোয়ারি চালাতে চাই।
— সামান্থা জেটি স্টার

টোলিস্ট () কাজ করবে তবে আপনি আপনার মন্তব্যে যেমন বলে গেছেন () একটি আইকোলিকেশন রিটার্ন করে, তাই আপনাকে কেবল আইকোলিকেশন <T> বা একটি আরও ভাল করার জন্য, আইকোলিকেশনটিতে ফিরে আসার স্বাক্ষর পরিবর্তন করতে হবে <T> । ToList বা ToArray ব্যবহার করে কাজ করবে তবে এটি একটি অপ্রয়োজনীয় স্মৃতি / অনুলিপি অপারেশনও করতে পারে
— ডঃ অ্যান্ড্রু বারনেট-থম্পসন

আপনি IENumerable এবং আইকোলিকেশন উভয়ের বিপরীতে লিনকিউ ক্যোয়ারী চালাতে পারেন। সুবিধাগুলি .. আমি এখনই জানি যে আইকোলিকেশনটি গণনা বজায় রাখে এবং এর কতগুলি আইটেম রয়েছে তা গণনা করে ফলাফলের ফলাফলের ফলাফল হয়। আইকোলিকেশন অতিরিক্ত অপসারণের পদ্ধতি সরবরাহ করে যা আয়করনযোগ্যগুলি হয় না
— হরিস হাসান

1

প্রশ্নে আরও তথ্য মুলতুবি:

দয়া করে আইটেমের ধরণ এবং গেটের স্বাক্ষর সম্পর্কে আরও তথ্য সরবরাহ করুন

দুটি জিনিস আপনি চেষ্টা করতে পারেন:

  • _Item এর রিটার্ন মান কাস্ট করতে (আইকোলিকেশন) এ পান
  • দ্বিতীয়ত _item.Get ("001") ব্যবহার করুন। ToArray () বা _item.Get ("001")। ToList ()

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


আপনার প্রশ্নের স্পষ্টতা এবং মন্তব্যে অনুসরণ করার পরে, আমি ব্যক্তিগতভাবে _item.Get ("001") আইকোল্লেশনে প্রত্যাবর্তন টাইপের ঘোষণা করব। এর অর্থ আপনাকে কোনও কাস্টিং বা রূপান্তর করতে হবে না (ToList / ToArray এর মাধ্যমে) যা অপ্রয়োজনীয় তৈরি / অনুলিপি অপারেশন জড়িত।

// Leave this the same
public ICollection<Item> Items { get; set; }

// Change function signature here:
// As you mention Item uses the same underlying type, just return an ICollection<T>
public ICollection<Item> Get(string value); 

// Ideally here you want to call .Count on the collectoin, not .Count() on 
// IEnumerable, as this will result in a new Enumerator being created 
// per loop iteration
for (var index = 0; index < Items.Count(); index++) 

শুভেচ্ছান্তে,


4
স্বাক্ষরটি হ'ল: অনুমানযোগ্য <টি> পান (স্ট্রিং পিকে); ফিরে আসা আইটেম রেকর্ডগুলি ধরে রাখতে আইটেমগুলি ব্যবহৃত হয়। পরে আমি প্রতিবেদন তৈরি করতে এগুলির মাধ্যমে পুনরাবৃত্তি করি। আমি যে কোনও কাজ করে তা ঠিক করে দেব। আপনার কি মনে হয় সেরা টাইপটি ডেটাটাইপটি হবে?
— সামান্থা জেটি স্টার

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

আমি পরে আইটেমগুলি কোথায় ব্যবহার করছি তা দেখাতে আমি প্রশ্নটিতে যুক্ত করেছি। একই অন্তর্নিহিত প্রকারটি বলার সময় আপনি সঠিক।
— সামান্থা জেটি স্টার

ঠিক আছে, তবে আমি কেবল গেটের রিটার্নের ধরণটি পরিবর্তন করব, তারপরে আপনাকে কোনও রূপান্তর (টোললিস্ট / টোআরয়ের মাধ্যমে যা ধীর) এর প্রয়োজন হবে না cast আশা করি এটি সাহায্য করে :)
— ডঃ অ্যান্ড্রু বারনেট-থম্পসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.