কনভার্ট লিস্ট <ডেরাইভড ক্লাস> কে <BaseClass> এ তালিকায় রাখুন


179

যদিও আমরা বেস ক্লাস / ইন্টারফেস থেকে উত্তরাধিকারী হতে পারি, কেন আমরা List<> একই শ্রেণি / ইন্টারফেস ব্যবহার করে ঘোষণা করতে পারি না ?

interface A
{ }

class B : A
{ }

class C : B
{ }

class Test
{
    static void Main(string[] args)
    {
        A a = new C(); // OK
        List<A> listOfA = new List<C>(); // compiler Error
    }
}

আশেপাশে কোন পথ আছে?


উত্তর:


230

এই কাজটি করার উপায়টি হল তালিকার উপরে পুনরাবৃত্তি করা এবং উপাদানগুলি কাস্ট করা। কনভার্টএল ব্যবহার করে এটি করা যেতে পারে:

List<A> listOfA = new List<C>().ConvertAll(x => (A)x);

আপনি লিনক ব্যবহার করতে পারেন:

List<A> listOfA = new List<C>().Cast<A>().ToList();

2
অন্য বিকল্প: তালিকা <A> listOfA = listOfC.ConvertAll (x => (A) x);
আহালিয়াভ শিয়াল

6
কোনটি দ্রুত? ConvertAllবা Cast?
মার্টিন ব্রাউন

24
এটি তালিকার একটি অনুলিপি তৈরি করবে। আপনি যদি নতুন তালিকায় কিছু যুক্ত বা সরিয়ে থাকেন তবে এটি মূল তালিকায় প্রতিফলিত হবে না। এবং দ্বিতীয়ত, এটি বিদ্যমান অবজেক্টগুলির সাথে একটি নতুন তালিকা তৈরি করার পরে একটি বড় কর্মক্ষমতা এবং মেমরি পেনাল্টি রয়েছে। এই সমস্যাগুলি ছাড়াই সমাধানের জন্য আমার উত্তরটি নীচে দেখুন।
বিগজিম

মোডিক্সের উত্তর: কনভার্টআল সমস্ত তালিকা <টি> তে একটি পদ্ধতি, সুতরাং এটি কেবল জেনেরিক তালিকায় কাজ করবে; এটি IEnumerable বা IEnumerable <T> এ কাজ করবে না; কনভার্টআল কেবল কাস্টিং নয় কাস্টম রূপান্তরও করতে পারে, যেমন কনভার্টএল (ইঞ্চি => ইঞ্চি * 25.4)। কাস্ট <A> একটি লিনকিউ এক্সটেনশন পদ্ধতি, সুতরাং যে কোনও আইএননামারেবল <T> (এবং অ-জেনেরিক আইমনিউরেবলের জন্যও কাজ করে) কাজ করে, এবং বেশিরভাগ লিনিকিউর মতো এটি পিছিয়ে দেওয়া কার্যকর ব্যবহার করে, যা কেবলমাত্র যতগুলি আইটেম রূপান্তরিত করে উদ্ধার করা হয়। এটি সম্পর্কে এখানে আরও পড়ুন: কোডব্লগ.জোনস্কেট.উইক
এডওয়ার্ড

172

সবার আগে, অসম্ভব-বোধগম্য বোঝার জন্য শ্রেণীর নাম যেমন এ, বি, সি ব্যবহার করা বন্ধ করুন প্রাণী, স্তন্যপায়ী, জিরাফ বা খাদ্য, ফল, কমলা বা এমন কিছু যেখানে সম্পর্কগুলি পরিষ্কার।

আপনার প্রশ্নটি তখন "আমি প্রাণীর টাইপের তালিকার বৈকল্পিকের জন্য জিরাফের তালিকা কেন বরাদ্দ করতে পারি না, যেহেতু আমি প্রকারের প্রাণীর বৈকল্পিককে জিরাফ দিতে পারি?"

উত্তরটি হ'ল ধরুন আপনি পারতেন। তাহলে কি ভুল হতে পারে?

ভাল, আপনি প্রাণীর তালিকায় একটি বাঘ যুক্ত করতে পারেন। মনে করুন আমরা আপনাকে একটি ভেরিয়েবলের মধ্যে জিরাফের একটি তালিকা রাখার অনুমতি দেব যা একটি প্রাণীর তালিকা রাখে। তারপরে আপনি সেই তালিকায় বাঘ যুক্ত করার চেষ্টা করুন। কি ঘটেছে? আপনি কি জিরাফের তালিকাতে একটি বাঘ থাকতে চান? আপনি কি একটি ক্রাশ চান? বা আপনি কি সংকলকটি প্রথমে অ্যাসাইনমেন্টটি বেআইনী করে ক্র্যাশ থেকে রক্ষা করতে চান?

আমরা পরেরটি নির্বাচন করি।

এই ধরণের রূপান্তরকে "সমবায়" রূপান্তর বলা হয়। সি # 4 এ রূপান্তরটি সর্বদা নিরাপদ বলে জানা গেলে আমরা আপনাকে ইন্টারফেস এবং প্রতিনিধিদের মধ্যে সমবায় রূপান্তর করতে অনুমতি দেব । তথ্যের জন্য সমবায় এবং বিপরীতে আমার ব্লগ নিবন্ধগুলি দেখুন। (এই সপ্তাহের সোমবার এবং বৃহস্পতিবার উভয় ক্ষেত্রেই এই বিষয়ে একটি নতুন বিষয় থাকবে))


3
আইএললিস্ট <টি> বা আইকোলিকেশন <টি> নন-জেনেরিক আইলিস্ট বাস্তবায়ন করা, তবে নন-জেনেরিক আইলিস্ট / আইকোলিকেশন রিটার্নটি বাস্তবায়নের ক্ষেত্রে ইস্রাডঅনলির জন্য সত্য, এবং সংশোধনকারী কোনও পদ্ধতি বা বৈশিষ্ট্যগুলির জন্য নোটসপোর্টডএক্সেপশন নিক্ষেপ করা সম্পর্কে কি কিছু সুরক্ষিত থাকবে?
সুপারক্যাট

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

2
@ এরিকলিপার্ট আমরা কেন এই পরিবর্তনের IEnumerableপরিবর্তে একটি ব্যবহার করতে পারি List? যেমন: List<Animal> listAnimals = listGiraffes as List<Animal>;সম্ভব নয়, তবে IEnumerable<Animal> eAnimals = listGiraffes as IEnumerable<Animal>কাজ করে।
লিনক

3
@ জবুউনো: আমার উত্তরের শেষ অনুচ্ছেদটি পড়ুন। সেখানে রূপান্তরটি নিরাপদ বলে জানা গেছে । কেন? কারণ জিরাফের ক্রমটিকে প্রাণীর অনুক্রমে পরিণত করা এবং তারপরে একটি বাঘকে প্রাণীর অনুক্রমে স্থাপন করা অসম্ভব । IEnumerable<T>এবং IEnumerator<T>উভয়ই সমবায় জন্য নিরাপদ হিসাবে চিহ্নিত হয়েছে, এবং সংকলক এটি যাচাই করেছে।
এরিক লিপার্ট

60

এরিকের দুর্দান্ত ব্যাখ্যাটি উদ্ধৃত করা

কি ঘটেছে? আপনি কি জিরাফের তালিকাতে একটি বাঘ থাকতে চান? আপনি কি একটি ক্রাশ চান? বা আপনি কি সংকলকটি প্রথমে অ্যাসাইনমেন্টটি বেআইনী করে ক্র্যাশ থেকে রক্ষা করতে চান? আমরা পরেরটি নির্বাচন করি।

তবে আপনি যদি একটি সংকলন ত্রুটির পরিবর্তে রানটাইম ক্র্যাশ বেছে নিতে চান? আপনি সাধারণত কাস্ট <> বা কনভার্টআল <> ব্যবহার করেন তবে তার পরে আপনার 2 টি সমস্যা হবে: এটি তালিকার একটি অনুলিপি তৈরি করবে। আপনি যদি নতুন তালিকায় কিছু যুক্ত করেন বা সরিয়ে থাকেন তবে এটি মূল তালিকায় প্রতিফলিত হবে না। এবং দ্বিতীয়ত, এটি বিদ্যমান অবজেক্টগুলির সাথে একটি নতুন তালিকা তৈরি করার পরে একটি বড় কর্মক্ষমতা এবং মেমরি পেনাল্টি রয়েছে।

আমার একই সমস্যা ছিল এবং তাই আমি একটি মোড়কের ক্লাস তৈরি করেছি যা সম্পূর্ণ নতুন তালিকা তৈরি না করে জেনেরিক তালিকা castালতে পারে।

মূল প্রশ্নে আপনি তখন ব্যবহার করতে পারেন:

class Test
{
    static void Main(string[] args)
    {
        A a = new C(); // OK
        IList<A> listOfA = new List<C>().CastList<C,A>(); // now ok!
    }
}

এবং এখানে মোড়কের ক্লাস (+ সহজ ব্যবহারের জন্য একটি এক্সটেনশন পদ্ধতি কাস্টলিস্ট)

public class CastedList<TTo, TFrom> : IList<TTo>
{
    public IList<TFrom> BaseList;

    public CastedList(IList<TFrom> baseList)
    {
        BaseList = baseList;
    }

    // IEnumerable
    IEnumerator IEnumerable.GetEnumerator() { return BaseList.GetEnumerator(); }

    // IEnumerable<>
    public IEnumerator<TTo> GetEnumerator() { return new CastedEnumerator<TTo, TFrom>(BaseList.GetEnumerator()); }

    // ICollection
    public int Count { get { return BaseList.Count; } }
    public bool IsReadOnly { get { return BaseList.IsReadOnly; } }
    public void Add(TTo item) { BaseList.Add((TFrom)(object)item); }
    public void Clear() { BaseList.Clear(); }
    public bool Contains(TTo item) { return BaseList.Contains((TFrom)(object)item); }
    public void CopyTo(TTo[] array, int arrayIndex) { BaseList.CopyTo((TFrom[])(object)array, arrayIndex); }
    public bool Remove(TTo item) { return BaseList.Remove((TFrom)(object)item); }

    // IList
    public TTo this[int index]
    {
        get { return (TTo)(object)BaseList[index]; }
        set { BaseList[index] = (TFrom)(object)value; }
    }

    public int IndexOf(TTo item) { return BaseList.IndexOf((TFrom)(object)item); }
    public void Insert(int index, TTo item) { BaseList.Insert(index, (TFrom)(object)item); }
    public void RemoveAt(int index) { BaseList.RemoveAt(index); }
}

public class CastedEnumerator<TTo, TFrom> : IEnumerator<TTo>
{
    public IEnumerator<TFrom> BaseEnumerator;

    public CastedEnumerator(IEnumerator<TFrom> baseEnumerator)
    {
        BaseEnumerator = baseEnumerator;
    }

    // IDisposable
    public void Dispose() { BaseEnumerator.Dispose(); }

    // IEnumerator
    object IEnumerator.Current { get { return BaseEnumerator.Current; } }
    public bool MoveNext() { return BaseEnumerator.MoveNext(); }
    public void Reset() { BaseEnumerator.Reset(); }

    // IEnumerator<>
    public TTo Current { get { return (TTo)(object)BaseEnumerator.Current; } }
}

public static class ListExtensions
{
    public static IList<TTo> CastList<TFrom, TTo>(this IList<TFrom> list)
    {
        return new CastedList<TTo, TFrom>(list);
    }
}

1
আমি স্রেফ এটি এমভিসি ভিউ মডেল হিসাবে ব্যবহার করেছি এবং দুর্দান্ত সার্বজনীন রেজারের আংশিক দৃশ্য পেয়েছি। আশ্চর্য ধারণা! আমি খুব খুশি যে আমি এটি পড়েছি।
স্টিফান সেবুলাক

5
ক্লাস ঘোষণায় আমি কেবলমাত্র "যেখানে টিটিও: টিফ্রোম" যুক্ত করব, তাই সংকলক ভুল ব্যবহারের বিরুদ্ধে সতর্ক করতে পারে। সম্পর্কযুক্ত প্রকারের একটি কাস্টলিস্ট তৈরি করা যাইহোক অযৌক্তিক এবং কোনও "ক্যাসিডলিস্ট <টিবেস, টিডেরাইভড" তৈরি করা অকেজো হবে: আপনি এটিতে নিয়মিত টিবেস অবজেক্ট যুক্ত করতে পারবেন না, এবং মূল তালিকা থেকে যে কোনও টিডিরিভড আপনি ইতিমধ্যে ব্যবহার করতে পারবেন একটি টিবেস।
ওল্ফজুন

2
@ পলকলডরে আলাস, একটি ছয় বছরের প্রধান সূচনা দোষারোপ করার জন্য।
ওল্ফজুন

@ ওল্ফজুন: স্ট্যান্ডার্ড। কাস্ট <টি> () তেমন কোনও বিধিনিষেধও নেই। আমি আচরণটি একইরকম করতে চাইছিলাম। অতএব তাই বাঘের তালিকায় প্রাণীর একটি তালিকা castালাই সম্ভব এবং উদাহরণস্বরূপ একটি জিরাফ থাকতে পারে তখন তার ব্যতিক্রম থাকতে পারে। ঠিক যেমন কাস্টের সাথে হবে ...
বিগজিম

হাই @ বিগজিম, আপনার র‍্যাপার ক্লাসটি কীভাবে ব্যবহার করতে হবে তা বুঝতে, জিরাফের একটি বিদ্যমান অ্যারে অ্যানিম্যাল (বেস ক্লাস) এ কাস্ট করতে আমার সমস্যা হচ্ছে। কোনও টিপস সংযোজন করা হবে :)
ডেনিস ভিটেজ

28

আপনি যদি এর IEnumerableপরিবর্তে ব্যবহার করেন তবে এটি কাজ করবে (কমপক্ষে সি # 4.0 এ, আমি পূর্ববর্তী সংস্করণগুলি ব্যবহার করে দেখিনি)। এটি কেবল একটি castালাই, অবশ্যই এটি এখনও একটি তালিকা হবে।

পরিবর্তে -

List<A> listOfA = new List<C>(); // compiler Error

প্রশ্নের মূল কোডটিতে, ব্যবহার করুন -

IEnumerable<A> listOfA = new List<C>(); // compiler error - no more! :)


এই ক্ষেত্রে আইমনামেবলকে কীভাবে ব্যবহার করবেন?
ভ্লাদিয়াস

1
List<A> listOfA = new List<C>(); // compiler Errorপ্রশ্নের মূল IEnumerable<A> listOfA = new List<C>(); // compiler error - no more! :)
কোডটির

আইমনামেবল <BaseClass> কে প্যারামিটার হিসাবে গ্রহণ করার পদ্ধতিটি উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণিকে তালিকা হিসাবে পাস করার অনুমতি দেবে। সুতরাং প্যারামিটারের ধরনটি পরিবর্তন করার খুব দরকার নেই।
beauXjames

27

যতদূর এটি কাজ করে না, ততই সাম্প্রদায়িকতা এবং বৈপরীত্য বোঝার জন্য এটি সহায়ক হতে পারে ।

কেন এটি কাজ করা উচিত নয় তা কেবল দেখানোর জন্য, আপনার দেওয়া কোডটিতে একটি পরিবর্তন রয়েছে:

void DoesThisWork()
{
     List<C> DerivedList = new List<C>();
     List<A> BaseList = DerivedList;
     BaseList.Add(new B());

     C FirstItem = DerivedList.First();
}

এই কাজ করা উচিত? তালিকার প্রথম আইটেমটি "বি" টাইপের, তবে ডেরিভডলিস্ট আইটেমের ধরণ সি।

এখন, ধরে নিন যে আমরা সত্যিই কেবল একটি জেনেরিক ফাংশন তৈরি করতে চাই যা কিছু প্রকারের তালিকায় কাজ করে যা এ প্রয়োগ করে, তবে কী ধরণের তা আমাদের যত্ন নেই:

void ThisWorks<T>(List<T> GenericList) where T:A
{

}

void Test()
{
     ThisWorks(new List<B>());
     ThisWorks(new List<C>());
}

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

16

আপনি কেবলমাত্র পঠনযোগ্য তালিকায় কাস্ট করতে পারেন। উদাহরণ স্বরূপ:

IEnumerable<A> enumOfA = new List<C>();//This works
IReadOnlyCollection<A> ro_colOfA = new List<C>();//This works
IReadOnlyList<A> ro_listOfA = new List<C>();//This works

এবং আপনি তালিকার জন্য এটি করতে পারবেন না যা সংরক্ষণের উপাদানগুলিকে সমর্থন করে। কারণ হ'ল:

List<string> listString=new List<string>();
List<object> listObject=(List<object>)listString;//Assume that this is possible
listObject.Add(new object());

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


1
এটি আমার কাছে সবচেয়ে বোধগম্য উত্তর ছিল। বিশেষত কারণ এটি উল্লেখ করেছে যে IReadOnlyList নামে কিছু আছে যা কাজ করবে কারণ এটি গ্যারান্টি দেয় যে আর কোনও উপাদান যুক্ত করা হবে না।
bendtherules

এটি লজ্জার বিষয় যে আপনি আইআরএডঅনালি ডিকোরিয়াস <টি কে, টিভিয়াল> এর জন্য একই রকম করতে পারবেন না। কেন এমন?
অ্যালাস্টার মাউ

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

1

আমি ব্যক্তিগতভাবে ক্লাসে এক্সটেনশান দিয়ে libs তৈরি করতে চাই

public static List<TTo> Cast<TFrom, TTo>(List<TFrom> fromlist)
  where TFrom : class 
  where TTo : class
{
  return fromlist.ConvertAll(x => x as TTo);
}

0

কারণ সি # এই ধরণের অনুমতি দেয় না উত্তরাধিকারএই মুহূর্তে রূপান্তর ।


6
প্রথমত, এটি রূপান্তরতার প্রশ্ন, উত্তরাধিকারের নয়। দ্বিতীয়ত, জেনেরিক প্রকারের স্বীকৃতি শ্রেণীর ধরণের উপর নির্ভর করে না, কেবল ইন্টারফেস এবং প্রতিনিধিদের ধরণের ক্ষেত্রে।
এরিক লিপার্ট

5
ভাল, আমি আপনার সাথে খুব তর্ক করতে পারি না।
দুপুর সিল্ক

0

এটি বিগজিমের উজ্জ্বল উত্তরের একটি বর্ধন ।

আমার ক্ষেত্রে অভিধানের NodeBaseসাথে আমার একটি ক্লাস ছিল Childrenএবং আমি বাচ্চাদের কাছ থেকে সাধারণভাবে ও (1) অনুসন্ধান করতে একটি উপায়ের প্রয়োজন ছিল। আমি প্রাইভেটরটিতে একটি ব্যক্তিগত অভিধান ক্ষেত্রটি ফেরত দেওয়ার চেষ্টা করছিলাম Children, তাই স্পষ্টতই আমি ব্যয়বহুল অনুলিপি / পুনরুক্তি এড়াতে চেয়েছিলাম। অতএব, আমি কাস্ট করার জন্য Bigjim এর কোড ব্যবহার করা Dictionary<whatever specific type>একটি জেনেরিক করতে Dictionary<NodeBase>:

// Abstract parent class
public abstract class NodeBase
{
    public abstract IDictionary<string, NodeBase> Children { get; }
    ...
}

// Implementing child class
public class RealNode : NodeBase
{
    private Dictionary<string, RealNode> containedNodes;

    public override IDictionary<string, NodeBase> Children
    {
        // Using a modification of Bigjim's code to cast the Dictionary:
        return new IDictionary<string, NodeBase>().CastDictionary<string, RealNode, NodeBase>();
    }
    ...
}

এটি ভাল কাজ করেছে। যাইহোক, আমি অবশেষে সম্পর্কিত নয় সীমাবদ্ধতার মধ্যে দৌড়েছি এবং FindChild()বেস ক্লাসে একটি বিমূর্ত পদ্ধতি তৈরি করে শেষ করেছি যা পরিবর্তে অনুসন্ধানগুলি করবে। এটি পরিণত হিসাবে এটি প্রথম স্থানে কাস্ট করা অভিধানের প্রয়োজনকে দূর করেছে। (আমি এটি IEnumerableআমার উদ্দেশ্যে একটি সাধারণ দিয়ে এটি প্রতিস্থাপন করতে সক্ষম হয়েছিল ।)

প্রশ্ন সুতরাং আপনি চাইতে পারি (বিশেষ করে যদি কর্মক্ষমতা একটি বিষয় ব্যবহার থেকে আপনাকে আটকানোর হয় .Cast<>বা .ConvertAll<>) হল:

"সত্যিই কি আমার পুরো সংগ্রহটি কাস্ট করা দরকার, বা আমি টাস্কটি সম্পাদন করার জন্য প্রয়োজনীয় বিশেষ জ্ঞান ধারণ করার জন্য কোনও বিমূর্ত পদ্ধতি ব্যবহার করতে পারি এবং এর মাধ্যমে সরাসরি সংগ্রহটি অ্যাক্সেস করা এড়াতে পারি?"

কখনও কখনও সহজ সমাধান সেরা।


0

এর সাথে System.Runtime.CompilerServices.Unsafeরেফারেন্স তৈরি করতে আপনি নিউগেট প্যাকেজটিও ব্যবহার করতে পারেন List:

using System.Runtime.CompilerServices;
...
class Tool { }
class Hammer : Tool { }
...
var hammers = new List<Hammer>();
...
var tools = Unsafe.As<List<Tool>>(hammers);

উপরের নমুনা দেওয়া, আপনি ভেরিয়েবলটি Hammerব্যবহার করে তালিকার বিদ্যমান উদাহরণগুলিতে অ্যাক্সেস করতে পারেন tools। যোগ করার পদ্ধতি Toolলিস্টে দৃষ্টান্ত একটি ছোঁড়ার ArrayTypeMismatchExceptionব্যতিক্রম কারণ toolsরেফারেন্স হিসাবে একই পরিবর্তনশীল hammers


0

আমি এই পুরো থ্রেডটি পড়েছি এবং আমি কেবল আমার কাছে কী অসঙ্গতি বলে মনে হয় তা উল্লেখ করতে চাই।

সংকলক আপনাকে তালিকা সহ অ্যাসাইনমেন্টটি করতে বাধা দেয়:

List<Tiger> myTigersList = new List<Tiger>() { new Tiger(), new Tiger(), new Tiger() };
List<Animal> myAnimalsList = myTigersList;    // Compiler error

কিন্তু সংকলক অ্যারেগুলির সাথে পুরোপুরি ঠিক আছে:

Tiger[] myTigersArray = new Tiger[3] { new Tiger(), new Tiger(), new Tiger() };
Animal[] myAnimalsArray = myTigersArray;    // No problem

অ্যাসাইনমেন্টটি নিরাপদ হিসাবে পরিচিত কিনা তা নিয়ে তর্কটি এখানে বিচ্ছিন্ন হয়ে পড়ে। অ্যারের সাথে আমি যে কাজটি করেছি তা নিরাপদ নয় । এটি প্রমাণ করার জন্য, আমি যদি এটির সাথে এটি অনুসরণ করি:

myAnimalsArray[1] = new Giraffe();

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

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