| Acknowledgments | xvii |
| Introduction | xix |
| PART I BASICS OF THE MICROSOFT .NET FRAMEWORK | |
| 1 The Architecture of the .NET Framework Development Platform | 3 |
| Compiling Source Code into Managed Modules | 3 |
| Combining Managed Modules into Assemblies | 7 |
| Loading the Common Language Runtime | 9 |
| Executing Your Assembly's Code | 11 |
| IL and Verification | 19 |
| The .NET Framework Class Library | 21 |
| The Common Type System | 24 |
| The Common Language Specification | 27 |
| Interoperability with Unmanaged Code | 31 |
| 2 Building, Packaging, Deploying, and Administering Applications and Types | 35 |
| .NET Framework Deployment Goals | 36 |
| Building Types into a Module | 37 |
| Combining Modules to Form an Assembly | 45 |
| Adding Assemblies to a Project Using the Visual Studio .NET IDE | 52 |
| Using the Assembly Linker | 53 |
| Including Resource Files in the Assembly | 55 |
| Assembly Version Resource Information | 56 |
| Version Numbers | 59 |
| Culture | 61 |
| Simple Application Deployment (Privately Deployed Assemblies) | 63 |
| Simple Administrative Control (Configuration) | 64 |
| 3 Shared Assemblies | 71 |
| Two Kinds of Assemblies, Two Kinds of Deployment | 72 |
| Giving an Assembly a Strong Name | 73 |
| The Global Assembly Cache | 79 |
| The Internal Structure of the GAC | 85 |
| Building an Assembly That References a Strongly Named Assembly | 87 |
| Strongly Named Assemblies Are Tamper-Resistant | 89 |
| Delayed Signing | 90 |
| Privately Deploying Strongly Named Assemblies | 95 |
| Side-by-Side Execution | 96 |
| How the Runtime Resolves Type References | 98 |
| Advanced Administrative Control (Configuration) | 101 |
| Publisher Policy Control | 106 |
| Repairing a Faulty Application | 109 |
| PART II WORKING WITH TYPES AND THE COMMON LANGUAGE RUNTIME | |
| 4 Type Fundamentals | 115 |
All Types Are Derived from System.Object | 115 |
| Casting Between Types | 117 |
Casting with the C# is and as Operators | 119 |
| Namespaces and Assemblies | 121 |
| 5 Primitive, Reference, and Value Types | 127 |
| Programming Language Primitive Types | 127 |
| Checked and Unchecked Primitive Type Operations | 131 |
| Reference Types and Values Types | 134 |
| Boxing and Unboxing Value Types | 141 |
| 6 Common Object Operations | 153 |
| Object Equality and Identity | 153 |
Implementing Equals for a Reference Type Whose Base Classes Don't Override Object's Equals | 154 |
Implementing Equals for a Reference Type When One or More of Its Base Classes Overrides Object's Equals | 156 |
Implementing Equals for a Value Type | 157 |
Summary of Implementing Equals and the ==/!= Operators | 160 |
| Identity | 161 |
| Object Hash Codes | 162 |
| Object Cloning | 164 |
| PART III DESIGNING TYPES | |
| 7 Type Members and Their Accessibility | 169 |
| Type Members | 169 |
| Accessibility Modifiers and Predefined Attributes | 173 |
| Type Predefined Attributes | 174 |
| Field Predefined Attributes | 175 |
| Method Predefined Attributes | 175 |
| 8 Constants and Fields | 177 |
| Constants | 177 |
| Fields | 178 |
| 9 Methods | 181 |
| Instance Constructors | 181 |
| Type Constructors | 187 |
| Operator Overload Methods | 190 |
| Operators and Programming Language Interoperability | 193 |
| Conversion Operator Methods | 197 |
| Passing Parameters by Reference to a Method | 200 |
| Passing a Variable Number of Parameters to a Method | 206 |
| How Virtual Methods Are Called | 209 |
| Virtual Method Versioning | 210 |
| 10 Properties | 215 |
| Parameterless Properties | 215 |
| Parameterful Properties | 220 |
| 11 Events | 227 |
| Designing a Type That Exposes an Event | 228 |
| Designing a Type That Listens for an Event | 234 |
| Explicitly Controlling Event Registration | 236 |
| Designing a Type That Defines Lots of Events | 238 |
Designing the EventHandlerSet Type | 243 |
| PART IV ESSENTIAL TYPES | |
| 12 Working with Text | 249 |
| Characters | 249 |
The System.String Type | 253 |
| Constructing Strings | 253 |
| Strings Are Immutable | 255 |
| Comparing Strings | 256 |
| String Interning | 262 |
| String Pooling | 266 |
| Examining a String's Characters | 266 |
| Other String Operations | 270 |
| Dynamically Constructing a String Efficiently | 270 |
Constructing a StringBuilder Object | 271 |
StringBuilder's Members | 272 |
| Obtaining a String Representation for an Object | 275 |
| Specific Formats and Cultures | 276 |
| Formatting Multiple Objects into a Single String | 280 |
| Providing Your Own Custom Formatter | 282 |
| Parsing a String to Obtain an Object | 285 |
| Encodings: Converting Between Characters and Bytes | 289 |
| Encoding/Decoding Streams of Characters and Bytes | 296 |
| Base-64 String Encoding and Decoding | 298 |
| 13 Enumerated Types and Bit Flags | 299 |
| Enumerated Types | 299 |
| Bit Flags | 305 |
| 14 Arrays | 309 |
All Arrays Are Implicitly Derived from System.Array | 312 |
| Casting Arrays | 315 |
| Passing and Returning Arrays | 316 |
| Creating Arrays That Have a Nonzero Lower Bound | 318 |
| Fast Array Access | 319 |
| Redimensioning an Array | 323 |
| 15 Interfaces | 325 |
| Interfaces and Inheritance | 325 |
| Designing an Application That Supports Plug-In Components | 331 |
| Changing Fields in a Boxed Value Type Using Interfaces | 333 |
| Implementing Multiple Interfaces That Have the Same Method | 336 |
| Explicit Interface Member Implementations | 338 |
| 16 Custom Attributes | 345 |
| Using Custom Attributes | 345 |
| Defining Your Own Attribute | 349 |
| Attribute Constructor and Field/Property Data Types | 353 |
| Detecting the Use of a Custom Attribute | 354 |
| Matching Two Attribute Instances Against Each Other | 359 |
| Pseudo-Custom Attributes | 362 |
| 17 Delegates | 365 |
| A First Look at Delegates | 365 |
| Using Delegates to Call Back Static Methods | 368 |
| Using Delegates to Call Back Instance Methods | 370 |
| Demystifying Delegates | 371 |
Some Delegate History: System.Delegate and System.MulticastDelegate | 375 |
| Comparing Delegates for Equality | 377 |
| Delegate Chains | 377 |
| C#'s Support for Delegate Chains | 383 |
| Having More Control over Invoking a Delegate Chain | 384 |
| Delegates and Reflection | 386 |
| PART V MANAGING TYPES | |
| 18 Exceptions | 393 |
| The Evolution of Exception Handling | 394 |
| The Mechanics of Exception Handling | 396 |
The try Block | 397 |
The catch Block | 398 |
The finally Block | 400 |
| What Exactly Is an Exception? | 401 |
The System.Exception Class | 406 |
| FCL-Defined Exception Classes | 408 |
| Defining Your Own Exception Class | 411 |
| How to Use Exceptions Properly | 416 |
You Can't Have Too Many finally Blocks | 416 |
| Don't Catch Everything | 418 |
| Gracefully Recovering from an Exception | 419 |
| Backing Out of a Partially Completed Operation When an Unrecoverable Exception Occurs | 420 |
| Hiding an Implementation Detail | 421 |
| What's Wrong with the FCL | 424 |
| Performance Considerations | 426 |
| Catch Filters | 429 |
| Unhandled Exceptions | 432 |
| Controlling What the CLR Does When an Unhandled Exception Occurs | 437 |
| Unhandled Exceptions and Windows Forms | 439 |
| Unhandled Exceptions and ASP.NET Web Forms | 440 |
| Unhandled Exceptions and ASP.NET XML Web Services | 441 |
| Exception Stack Traces | 441 |
| Remoting Stack Traces | 444 |
| Debugging Exceptions | 445 |
| Telling Visual Studio What Kind of Code to Debug | 448 |
| 19 Automatic Memory Management (Garbage Collection) | 451 |
| Understanding the Basics of Working in a Garbage-Collected Platform | 451 |
| The Garbage Collection Algorithm | 455 |
| Finalization | 459 |
What Causes Finalize Methods to Get Called | 467 |
| Finalization Internals | 468 |
| The Dispose Pattern: Forcing an Object to Clean Up | 471 |
| Using a Type That Implements the Dispose Pattern | 477 |
C#'s using Statement | 482 |
| An Interesting Dependency Issue | 484 |
| Weak References | 485 |
| Weak Reference Internals | 487 |
| Resurrection | 489 |
| Designing an Object Pool Using Resurrection | 491 |
| Generations | 493 |
| Programmatic Control of the Garbage Collector | 499 |
| Other Garbage Collector Performance Issues | 501 |
| Synchronization-Free Allocations | 503 |
| Scalable Parallel Collections | 503 |
| Concurrent Collections | 504 |
| Large Objects | 505 |
| Monitoring Garbage Collections | 506 |
| 20 CLR Hosting, AppDomains, and Reflection | 507 |
| Metadata: The Cornerstone of the .NET Framework | 507 |
| CLR Hosting | 508 |
| AppDomains | 510 |
| Accessing Objects Across AppDomain Boundaries | 513 |
| AppDomain Events | 515 |
| Applications and How They Host the CLR and Manage AppDomains | 516 |
| "Yukon" | 517 |
| The Gist of Reflection | 518 |
| Reflecting Over an Assembly's Types | 520 |
| Reflecting Over an AppDomain's Assemblies | 523 |
| Reflecting Over a Type's Members: Binding | 523 |
| Explicitly Loading Assemblies | 525 |
| Loading Assemblies as "Data Files" | 527 |
Building a Hierarchy of Exception-Derived Types | 529 |
| Explicitly Unloading Assemblies: Unloading an AppDomain | 532 |
Obtaining a Reference to a System.Type Object | 534 |
| Reflecting Over a Type's Members | 538 |
| Creating an Instance of a Type | 541 |
| Calling a Type's Method | 543 |
| Bind Once, Invoke Multiple Times | 548 |
| Reflecting Over a Type's Interfaces | 553 |
| Reflection Performance | 555 |
| INDEX | 557 |