What are Generics?
Generics enable you to write code that works with different types while still maintaining type safety. Instead of using dynamic (which disables type checking), generics allow you to specify a type parameter that is resolved at compile time. This leads to reusable components (like collections) that are safe and efficient. Dart's collection classes, such as List<E> and Map<K,V>, are prime examples of generics.
Why Use Generics?
- Type safety – catch type errors at compile time.
- Code reuse – write a single class or function that works with many types.
- Eliminates casting – no need for explicit casts, reducing runtime errors.
- Better documentation – the expected type is clear from the signature.
Generic Functions
You can declare a generic function by placing a type parameter in angle brackets before the return type. The type parameter can be used in parameters and return types.
Generic Classes
A class can have one or more type parameters. You can then instantiate the class with specific types. This is how built‑in collections work.
Multiple Type Parameters
You can use multiple type parameters, separated by commas. This is common for key‑value containers like maps.
Type Constraints with extends
Sometimes you need to restrict the types that can be used with a generic. Use the extends keyword to specify an upper bound. The type parameter must be a subtype of the bound.
Using Comparable with Bounds
Constraints are often used to ensure that types can be compared or have specific methods. For example, you can require that a type implements Comparable.
Generic Methods in Non‑Generic Classes
Even if a class isn't generic, you can still have generic methods inside it. The type parameter is scoped to the method.
Understanding dynamic vs Generics
Using dynamic bypasses type checking entirely, which can lead to runtime errors. Generics preserve type information, catching mistakes early.
Key Takeaways
- Generics allow writing type‑safe, reusable code.
- Use
<T>for type parameters in classes, methods, and functions.
- Use
- Multiple type parameters are supported (e.g.,
<K, V>).
- Multiple type parameters are supported (e.g.,
- Use
extendsto constrain type parameters to a supertype.
- Use
- Generics help avoid casting and reduce runtime errors.
- Prefer generics over
dynamicwhen possible.
- Prefer generics over