Pro CSharp 2008 And The .NET 3.5 Platform [eng]-1
.pdfThe EXPERT’s VOIce® in .NET
For a limitedli i time,i ,
get the free,, fullylly searchablele eBook—a $30 value!l
Seeee lastlast pagepage forfor detailsdetails.. Offerffer endsends JuneJune 30,30,20082008..
Pro
C# 2008 and
the
.NET 3.5 Platform
Exploring the .NET universe using curly brackets
Fourth Edition
Andrew Troelsen
Pro C# 2008 and the
.NET 3.5 Platform
Fourth Edition
Andrew Troelsen
Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition
Copyright © 2007 by Andrew Troelsen
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher.
ISBN-13: 978-1-59059-884-9
ISBN-10: 1-59059-884-9
Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1
Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark.
Lead Editor: Ewan Buckingham
Technical Reviewer: Gavin Smyth
Editorial Board: Steve Anglin, Ewan Buckingham, Tony Campbell, Gary Cornell, Jonathan Gennick, Jason Gilmore, Kevin Goff, Jonathan Hassell, Matthew Moodie, Joseph Ottinger, Jeffrey Pepper, Ben Renow-Clarke, Dominic Shakeshaft, Matt Wade, Tom Welsh
Production Director | Project Manager: Grace Wong Senior Copy Editors: Ami Knox, Nicole Flores Associate Production Director: Kari Brooks-Copony Production Editor: Ellie Fountain
Compositor: Dina Quan
Proofreaders: April Eddy and Liz Welch Indexer: Broccoli Information Management Artist: Kinetic Publishing Services, LLC Cover Designer: Kurt Krames Manufacturing Director: Tom Debolski
Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail orders-ny@springer-sbm.com, or visit http://www.springeronline.com.
For information on translations, please contact Apress directly at 2855 Telegraph Avenue, Suite 600, Berkeley, CA 94705. Phone 510-549-5930, fax 510-549-5939, e-mail info@apress.com, or visit http://www.apress.com.
The information in this book is distributed on an “as is” basis, without warranty. Although every precaution has been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in this work.
The source code for this book is available to readers at http://www.apress.com in the Source Code/ Download section. You will need to answer questions pertaining to this book in order to successfully download the code.
This edition of the text is dedicated to Mikko the wonder cat, life at 412, and my wonderful wife, Amanda, who patiently waited for me to finish yet another book.
Contents
About the Author. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Part 1 ■ ■ ■ Introducing C# and the .NET Platform
■CHAPTER 1 The Philosophy of .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Understanding the Previous State of Affairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
The .NET Solution. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Introducing the Building Blocks of the .NET Platform (the CLR, CTS,
and CLS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Additional .NET-Aware Programming Languages. . . . . . . . . . . . . . . . . . . . . . . . . . . 9
An Overview of .NET Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Understanding the Common Type System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Understanding the Common Language Specification . . . . . . . . . . . . . . . . . . . . . . 20 Understanding the Common Language Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . 22 The Assembly/Namespace/Type Distinction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Exploring an Assembly Using ildasm.exe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Exploring an Assembly Using Lutz Roeder’s Reflector. . . . . . . . . . . . . . . . . . . . . . 31
Deploying the .NET Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
The Platform-Independent Nature of .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
■CHAPTER 2 Building C# Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
The Role of the .NET Framework 3.5 SDK. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Building C# Applications Using csc.exe. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Building .NET Applications Using TextPad. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Building .NET Applications Using Notepad++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Building .NET Applications Using SharpDevelop. . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Building .NET Applications Using Visual C# 2008 Express . . . . . . . . . . . . . . . . . . 50 Building .NET Applications Using Visual Studio 2008 . . . . . . . . . . . . . . . . . . . . . . 52 A Partial Catalog of Additional .NET Development Tools . . . . . . . . . . . . . . . . . . . . 64
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
iv
■CONTENTS v
Part 2 ■ ■ ■ Core C# Programming Constructs
■CHAPTER 3 |
Core C# Programming Constructs, Part I . . . . . . . . . . . . . . . . . . . . . . . . |
. 69 |
|
The Anatomy of a Simple C# Program. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
. 69 |
|
An Interesting Aside: Some Additional Members of the |
|
|
System.Environment Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
. 75 |
|
The System.Console Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
. 76 |
|
System Data Types and C# Shorthand Notation. . . . . . . . . . . . . . . . . . . . . . . . . . |
. 80 |
|
Understanding the System.String Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
. 86 |
|
Narrowing and Widening Data Type Conversions. . . . . . . . . . . . . . . . . . . . . . . . . |
. 95 |
|
C# Iteration Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
100 |
|
Decision Constructs and the Relational/Equality Operators. . . . . . . . . . . . . . . . . |
102 |
|
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
104 |
■CHAPTER 4 |
Core C# Programming Constructs, Part II . . . . . . . . . . . . . . . . . . . . . . . . |
107 |
|
Methods and Parameter Modifiers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
107 |
|
Understanding Member Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
113 |
|
Array Manipulation in C#. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
114 |
|
Understanding the Enum Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
121 |
|
Understanding the Structure Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
126 |
|
Understanding Value Types and Reference Types . . . . . . . . . . . . . . . . . . . . . . . . |
129 |
|
Value and Reference Types: Final Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
135 |
|
Understanding C# Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
136 |
|
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
139 |
■CHAPTER 5 |
Defining Encapsulated Class Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
141 |
|
Introducing the C# Class Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
141 |
|
Understanding Class Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
144 |
|
The Role of the this Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
147 |
|
Understanding the static Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
152 |
|
Defining the Pillars of OOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
159 |
|
C# Access Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
163 |
|
The First Pillar: C#’s Encapsulation Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
164 |
|
Understanding Constant Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
173 |
|
Understanding Read-Only Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
174 |
|
Understanding Partial Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
175 |
|
Documenting C# Source Code via XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
176 |
|
Visualizing the Fruits of Our Labor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
182 |
|
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
182 |
■CHAPTER 6 |
Understanding Inheritance and Polymorphism . . . . . . . . . . . . . . . . . . |
185 |
|
The Basic Mechanics of Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
185 |
|
Revising Visual Studio Class Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
189 |
|
The Second Pillar: The Details of Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
190 |
|
Programming for Containment/Delegation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
196 |
vi |
■CONTENTS |
|
|
|
|
The Third Pillar: C#’s Polymorphic Support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
199 |
|
|
Understanding Base Class/Derived Class Casting Rules . . . . . . . . . . . . . . . . . . . |
210 |
|
|
The Master Parent Class: System.Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
212 |
|
|
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
218 |
|
■CHAPTER 7 |
Understanding Structured Exception Handling. . . . . . . . . . . . . . . . . . . |
219 |
|
|
Ode to Errors, Bugs, and Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
219 |
|
|
The Role of .NET Exception Handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
220 |
|
|
The Simplest Possible Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
222 |
|
|
Configuring the State of an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
226 |
|
|
System-Level Exceptions (System.SystemException) . . . . . . . . . . . . . . . . . . . . . |
230 |
|
|
Application-Level Exceptions (System.ApplicationException) . . . . . . . . . . . . . . . |
231 |
|
|
Processing Multiple Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
236 |
|
|
The Finally Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
239 |
|
|
Who Is Throwing What? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
240 |
|
|
The Result of Unhandled Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
241 |
|
|
Debugging Unhandled Exceptions Using Visual Studio . . . . . . . . . . . . . . . . . . . . |
242 |
|
|
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
243 |
|
■CHAPTER 8 |
Understanding Object Lifetime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
245 |
|
|
Classes, Objects, and References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
245 |
|
|
The Basics of Object Lifetime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
246 |
|
|
The Role of Application Roots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
249 |
|
|
Understanding Object Generations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
251 |
|
|
The System.GC Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
252 |
|
|
Building Finalizable Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
256 |
|
|
Building Disposable Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
259 |
|
|
Building Finalizable and Disposable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
262 |
|
|
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
265 |
Part 3 ■ ■ ■ Advanced C# Programming Constructs
■CHAPTER 9 Working with Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Understanding Interface Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Defining Custom Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Implementing an Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Invoking Interface Members at the Object Level . . . . . . . . . . . . . . . . . . . . . . . . . 276
Interfaces As Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Interfaces As Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Arrays of Interface Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Implementing Interfaces Using Visual Studio 2008 . . . . . . . . . . . . . . . . . . . . . . . 282
Resolving Name Clashes via Explicit Interface Implementation . . . . . . . . . . . . . 283
Designing Interface Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Building Enumerable Types (IEnumerable and IEnumerator) . . . . . . . . . . . . . . . 289
Building Cloneable Objects (ICloneable) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
■CONTENTS vii
Building Comparable Objects (IComparable). . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Understanding Callback Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
■CHAPTER 10 Collections and Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
The Interfaces of the System.Collections Namespace . . . . . . . . . . . . . . . . . . . . . 309
The Class Types of System.Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
System.Collections.Specialized Namespace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
The Boxing, Unboxing, and System.Object Relationship . . . . . . . . . . . . . . . . . . . 316
The Issue of Type Safety and Strongly Typed Collections . . . . . . . . . . . . . . . . . . 319
The System.Collections.Generic Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Creating Custom Generic Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Creating Generic Structures and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
Creating a Custom Generic Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Creating Generic Base Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Creating Generic Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
■CHAPTER 11 Delegates, Events, and Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Understanding the .NET Delegate Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Defining a Delegate in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
The System.MulticastDelegate and System.Delegate Base Classes . . . . . . . . . 344
The Simplest Possible Delegate Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Retrofitting the Car Type with Delegates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
A More Elaborate Delegate Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Understanding Delegate Covariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
Creating Generic Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Understanding C# Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
The Generic EventHandler<T> Delegate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Understanding C# Anonymous Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Understanding Method Group Conversions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
The C# 2008 Lambda Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
■CHAPTER 12 Indexers, Operators, and Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
383 |
Understanding Indexer Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Understanding Operator Overloading. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
Understanding Custom Type Conversions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Working with Pointer Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
C# Preprocessor Directives. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
■CHAPTER 13 C# 2008 Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Understanding Implicitly Typed Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Understanding Automatic Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Understanding Extension Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
viii ■CONTENTS
Understanding Partial Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Understanding Object Initializer Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Understanding Anonymous Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
■CHAPTER 14 An Introduction to LINQ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Understanding the Role of LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
A First Look at LINQ Query Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
LINQ and Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
LINQ and Nongeneric Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
The Internal Representation of LINQ Query Operators . . . . . . . . . . . . . . . . . . . . . 459
Investigating the C# LINQ Query Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
LINQ Queries: An Island unto Themselves?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
PART 4 ■ ■ ■ Programming with .NET Assemblies
■CHAPTER 15 Introducing .NET Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Defining Custom Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
The Role of .NET Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
Understanding the Format of a .NET Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . 482
Building and Consuming a Single-File Assembly . . . . . . . . . . . . . . . . . . . . . . . . . 486
Building and Consuming a Multifile Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
Understanding Private Assemblies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
Understanding Shared Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Consuming a Shared Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
Configuring Shared Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Investigating the Internal Composition of the GAC . . . . . . . . . . . . . . . . . . . . . . . . 516
Understanding Publisher Policy Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Understanding the <codeBase> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
The System.Configuration Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
The Machine Configuration File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
■CHAPTER 16 Type Reflection, Late Binding, and Attribute-Based |
|
Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
523 |
The Necessity of Type Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Understanding Reflection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
Building a Custom Metadata Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
Dynamically Loading Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
Reflecting on Shared Assemblies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Understanding Late Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
■CONTENTS ix
Understanding Attributed Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Building Custom Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Assembly-Level (and Module-Level) Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . 549
Reflecting on Attributes Using Early Binding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Reflecting on Attributes Using Late Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
Putting Reflection, Late Binding, and Custom Attributes in Perspective . . . . . . 553
Building an Extendable Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
■CHAPTER 17 Processes, AppDomains, and Object Contexts . . . . . . . . . . . . . . . . . . . 561
Reviewing Traditional Win32 Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
Interacting with Processes Under the .NET Platform . . . . . . . . . . . . . . . . . . . . . . 563
Understanding .NET Application Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
Understanding Object Context Boundaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
Summarizing Processes, AppDomains, and Context . . . . . . . . . . . . . . . . . . . . . . 581
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
■CHAPTER 18 Building Multithreaded Applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
The Process/AppDomain/Context/Thread Relationship . . . . . . . . . . . . . . . . . . . . 583
A Brief Review of the .NET Delegate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
The Asynchronous Nature of Delegates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
Invoking a Method Asynchronously . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
The System.Threading Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
The System.Threading.Thread Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
Programmatically Creating Secondary Threads . . . . . . . . . . . . . . . . . . . . . . . . . . 597
The Issue of Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602
Programming with Timer Callbacks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609
Understanding the CLR ThreadPool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 610
The Role of the BackgroundWorker Component. . . . . . . . . . . . . . . . . . . . . . . . . . 612
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616
■CHAPTER 19 Understanding CIL and the Role of Dynamic Assemblies . . . . . . . . |
617 |
Reflecting on the Nature of CIL Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . 617 Examining CIL Directives, Attributes, and Opcodes . . . . . . . . . . . . . . . . . . . . . . . 618 Pushing and Popping: The Stack-Based Nature of CIL . . . . . . . . . . . . . . . . . . . . 620
Understanding Round-Trip Engineering. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
Understanding CIL Directives and Attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
.NET Base Class Library, C#, and CIL Data Type Mappings . . . . . . . . . . . . . . . . 635
Defining Type Members in CIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636 Examining CIL Opcodes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638 Building a .NET Assembly with CIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643 Understanding Dynamic Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657