Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Generics vs non-generics in C#
There are two main types of collections in C#: generic collections and non-generic collections. The primary difference lies in type safety, performance, and how they handle different data types.
Generic Collections
Generic collections are type-safe and hold elements of the same data type. They provide better performance as they avoid boxing and unboxing operations for value types.
Key Features
Type Safety: Compile-time type checking prevents runtime errors
Better Performance: No boxing/unboxing for value types
IntelliSense Support: Better code completion and error detection
Common Generic Collections
List<T>− Dynamic array of type TDictionary<TKey, TValue>− Key-value pairs with specific typesHashSet<T>− Unique elements of type T
Example
using System;
using System.Collections.Generic;
class GenericExample {
public static void Main() {
// List of integers only
List<int> numbers = new List<int>();
numbers.Add(10);
numbers.Add(20);
// numbers.Add("string"); // Compile-time error
Console.WriteLine("Generic List:");
foreach(int num in numbers) {
Console.WriteLine(num);
}
// Dictionary with string keys and int values
Dictionary<string, int> ages = new Dictionary<string, int>();
ages["Alice"] = 25;
ages["Bob"] = 30;
Console.WriteLine("\nGeneric Dictionary:");
foreach(var pair in ages) {
Console.WriteLine(pair.Key + ": " + pair.Value);
}
}
}
The output of the above code is −
Generic List: 10 20 Generic Dictionary: Alice: 25 Bob: 30
Non-Generic Collections
Non-generic collections can hold elements of different data types but lack type safety. They store elements as object type, requiring casting when retrieving values.
Key Features
Mixed Data Types: Can store different types in the same collection
Boxing/Unboxing: Value types are boxed, causing performance overhead
Runtime Errors: Type mismatches discovered only at runtime
Common Non-Generic Collections
ArrayList− Dynamic array that can hold any object typeHashtable− Key-value pairs without type restrictionsBitArray− Array of boolean values represented as bits
Example
using System;
using System.Collections;
class NonGenericExample {
public static void Main() {
// ArrayList can hold different types
ArrayList mixedList = new ArrayList();
mixedList.Add(10); // int
mixedList.Add("Hello"); // string
mixedList.Add(3.14); // double
mixedList.Add(true); // bool
Console.WriteLine("Non-Generic ArrayList:");
foreach(object item in mixedList) {
Console.WriteLine(item + " (Type: " + item.GetType().Name + ")");
}
// Hashtable with mixed key-value types
Hashtable table = new Hashtable();
table[1] = "One";
table["Two"] = 2;
table[3.0] = "Three";
Console.WriteLine("\nNon-Generic Hashtable:");
foreach(DictionaryEntry entry in table) {
Console.WriteLine(entry.Key + ": " + entry.Value);
}
}
}
The output of the above code is −
Non-Generic ArrayList: 10 (Type: Int32) Hello (Type: String) 3.14 (Type: Double) True (Type: Boolean) Non-Generic Hashtable: 3: Three 1: One Two: 2
Comparison
| Aspect | Generic Collections | Non-Generic Collections |
|---|---|---|
| Type Safety | Compile-time type checking | Runtime type checking only |
| Performance | Better (no boxing/unboxing) | Slower (boxing/unboxing required) |
| Mixed Types | Not allowed | Allowed |
| IntelliSense | Full support with type information | Limited support |
| Memory Usage | More efficient | Higher overhead |
Type Safety Demonstration
Example
using System;
using System.Collections;
using System.Collections.Generic;
class TypeSafetyExample {
public static void Main() {
// Generic - Type safe
List<string> genericList = new List<string>();
genericList.Add("Hello");
genericList.Add("World");
// Direct access without casting
string firstItem = genericList[0];
Console.WriteLine("Generic: " + firstItem);
// Non-Generic - Requires casting
ArrayList nonGenericList = new ArrayList();
nonGenericList.Add("Hello");
nonGenericList.Add("World");
// Casting required and potential runtime error
string firstNonGeneric = (string)nonGenericList[0];
Console.WriteLine("Non-Generic: " + firstNonGeneric);
// This would cause runtime error if uncommented
// nonGenericList.Add(123);
// string wrongCast = (string)nonGenericList[2]; // Runtime exception
}
}
The output of the above code is −
Generic: Hello Non-Generic: Hello
Conclusion
Generic collections provide type safety, better performance, and enhanced development experience through compile-time checking. Non-generic collections offer flexibility for mixed data types but sacrifice type safety and performance. Modern C# development favors generic collections for their reliability and efficiency.
