Sobes.tech
Middle

What are generics and how are they used in programming?

sobes.tech AI

Answer from AI

Generics are a feature that allows creating classes, interfaces, and methods that can work with different data types while ensuring type safety at compile time.

Main advantages of using generics:

  • Type safety: The compiler checks types at compile time, preventing runtime errors due to type mismatches.
  • Code reuse: You can write universal code that works with different data types without duplicating it for each type.
  • Improved code readability: Explicitly specifying the types with which a generic class/method works makes the code more understandable.

Examples of usage:

Collections: One of the most common applications of generics is creating type-safe collections (e.g., lists, sets, maps).

List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
// names.add(123); // Compilation error: incompatible types

Map<Integer, String> users = new HashMap<>();
users.put(1, "Charlie");
users.put(2, "Diana");

Custom generic classes: You can create your own classes that work with generic types.

public class Box<T> // T is a type parameter
{
    private T content;

    public Box(T content)
    {
        this.content = content;
    }

    public T GetContent()
    {
        return content;
    }
}

// Using a generic class
Box<string> stringBox = new Box<string>("Hello");
Console.WriteLine(stringBox.GetContent());

Box<int> intBox = new Box<int>(123);
Console.WriteLine(intBox.GetContent());

Generic methods: Methods can also be generic, allowing them to work with various data types without overloading for each type.

from typing import List, TypeVar

T = TypeVar('T')

def process_list(data: List[T]) -> None:
    # Processing a list of elements of type T
    for item in data:
        print(item)

# Using a generic method
process_list([1, 2, 3])
process_list(["a", "b", "c"])

Type constraints: In some languages, you can impose constraints on the types that generics can work with, such as requiring the type to implement a specific interface or inherit from a certain class.

public class Storage<T> where T : IComparable // T must implement IComparable
{
    private T item;

    public Storage(T item)
    {
        this.item = item;
    }

    public bool IsGreater(T other)
    {
        return item.CompareTo(other) > 0;
    }
}

Generics significantly contribute to writing flexible, type-safe, and well-maintained code.