8.1. Equality, Hashing, and Comparison8.1.1. Asserting Equality, Hashing, and Comparison Using Attributes8.1.2. Fully Customizing Equality, Hashing, and Comparison on a Type8.1.3. Suppressing Equality, Hashing, and Comparison on a Type8.1.4. Customizing Generic Collection Types8.2. Efficient Precomputation and Caching8.2.1. Precomputation and Partial Application8.2.2. Precomputation and Objects8.2.3. Memoizing Computations8.2.4. Lazy Values8.2.5. Other Variations on Caching and Memoization8.3. Cleaning Up Resources8.3.1. Cleaning Up with use8.3.2. Managing Resources with More Complex Lifetimes8.3.3. Cleaning Up Internal Objects8.3.4. Cleaning Up Unmanaged Objects8.3.5. Cleaning Up in Sequence Expressions8.3.6. Using using8.4. Stack as a Resource: Tail Calls and Recursion8.4.1. Tail Recursion and List Processing8.4.2. Tail Recursion and Object-Oriented Programming8.4.3. Tail Recursion and Processing Unbalanced Trees8.4.4. Using Continuations to Avoid Stack Overflows8.4.5. Another Example: Processing Syntax Trees8.5. Events8.5.1. Events as First-Class Values8.5.2. Creating and Publishing Events8.6. Summary