در این مقایسه سعی شده مطالب بصورت خلاصه و مفید مطرح بشه. جهت اطلاعات دقیقتر به مستندات دات نت فریمورک مراجعه نمایید.

همانطور که میدونید ما دو مدل کالکشن داریم :
  1. کالکشنهای معمولی (مثل ArrayList)
  2. کالکشنهای ژنریک (مثل <>List)

در مورد کالکشنهای ساده :
چون توسعه دهندگان دات نت نمیدونستند که استفاده کنندگان قراره چه چیزی رو درون یک کالکشن بریزند (در واقع هرچیزی ممکنه : از یک نمونه person گرفته تا یک عدد یا رشته) اومدن و گفتن کالکشنهای ما آیتمهایی از نوع Object قبول میکنه در نتیجه برنامه نویسان بعدی میتونستند هرچیزی رو در آن نگهداری کنند. این داستان دو مشکل عمده دارد :
1- Boxing و unBoxing : یعنی شما زمانی که یک آیتم را به لیست اضافه میکنید باید تبدیل به یک Object شه (boxing) و زمانی که اون رو از لیست میخونید باید اون رو به تایپ مورد نظر خودتون cast کنید(unboxing) که این موضوع پر هزینه ای است.
2- Type safety وجود ندارد. یعنی شما هرچیزی رو میتونید درون یک arrayList بریزید بدون آنکه کامپایلر به شما هشدار دهد و گاه با یک اشتباه کوچیک برنامه شما در زمان اجرا crach میکند.
ArrayList list = new ArrayList();
list.Add(new Person());
list.Add("new Person()"); // its ok at compile time!
list.Add(new Person());


و اما در
کالکشنهای ژنریک (که با دات نت 2.0 آغاز شدند) شما در زمان کد نویسی مشخص میکنید که با چه تایپی میخواهید کار کنید. این موضوع دو حسن کلی دارد :
1- عملیات boxing و unboxing حذف و لذا performace بیشتر میشود
2- عملیات افزودن آیتم به لیست safe میشود چون اگر چیزی غیر از آنچه مشخص شده را درون لیست بریزید در کامپایل تایم به error برمیخورید.
List<Person> persons = new List<Person>();
persons.Add(new Person());
persons.Add("new Person()"); // error in compile time
persons.Add(new Person());