# Skill 07 - Interfaces, Generics, Events, Operators, and Inheritance ## Interfaces - Use interfaces to model capabilities or contracts, not every class by default. - Keep interfaces small and cohesive. - Prefer dependency inversion at boundaries: data stores, clocks, HTTP clients, external services, email, files, and message queues. - Do not create one-to-one interfaces for every implementation unless mocking, plugin replacement, or architecture requires it. ## Generics - Use generics for type-safe reuse. - Add constraints (`where T : ...`) to express required capabilities. - Prefer `IEnumerable` for simple read-only enumeration, `IReadOnlyList` when count/index matters, and concrete collections when mutation is required internally. ## Events and Delegates - Use events for notifications from one object to many subscribers. - Prefer standard `EventHandler` / `EventHandler` unless a custom delegate adds clarity. - Avoid memory leaks by unsubscribing long-lived event subscriptions. ## Operator Overloading - Overload operators only when they match natural domain meaning. - Keep overloaded operators unsurprising and consistent with equality/comparison. ## Inheritance - Prefer composition over inheritance for code reuse. - Use inheritance for true "is-a" relationships. - Mark base members `virtual` only when overriding is intended. - Use `override` deliberately and keep base class contracts intact. - Use `sealed` for classes or overrides that should not be extended. - Use pattern matching or safe casts rather than unsafe casts. ## Extension Members - Use extension methods to add convenience behavior to types you do not own. - Keep extension methods pure and obvious. - Do not hide expensive I/O behind innocent-looking extension methods.