All our code so far has been very specific in terms of defining and using types. However, there will be cases when you need a class or method to treat its entities in the same way, no matter their type, while still being type-safe. Generic programming allows us to create reusable classes, methods, and variables using a placeholder rather than a concrete type.
When a generic class instance is created or a method is used, a concrete type will be assigned, but the code itself treats it as a generic type. You'll see generic programming most often in custom collection types that need to be able to perform the same operations on elements regardless of type. While this might not conceptually make sense yet, it will once when we look at a concrete example in the next section.