C# 3.0 the complete reference - herbert schildt

913

Transcript of C# 3.0 the complete reference - herbert schildt

  • 1. C# 3.0:The Complete ReferencePresented By: Oronno - "The ONE"www.the1.co.nr

2. About the AuthorHerbert Schildt is a leading authority on C#, C++, C,and Java. His programming books have sold more than3.5 million copies worldwide and have been translatedinto all major foreign languages. He is the author ofnumerous bestsellers, including Java: The CompleteReference, C++: The Complete Reference, C: The CompleteReference, and C#: A Beginners Guide. Although interestedin all facets of computing, his primary focus is computerlanguages, including compilers, interpreters, and roboticcontrol languages. He also has an active interest in thestandardization of languages. Schildt holds both graduateand undergraduate degrees from the University of Illinois.He can be reached at his consulting office at (217) 586-4683.His web site is www.HerbSchildt.com.About the Technical EditorMichael Howard (Austin, Texas) is a principal securityprogram manager on the Trustworthy Computing(TwC) Groups Security Engineering team at Microsoft,where he is responsible for managing secure design,programming, and testing techniques across thecompany. Howard is an architect of the SecurityDevelopment Lifecycle (SDL), a process for improvingthe security of Microsofts software. Howard speaksregularly on the topic of securing code for Microsoftand at conferences worldwide. He regularly publishesarticles on security design and is the co-author of sixsecurity books, including the award-winning WritingSecure Code, 19 Deadly Sins of Software Security, The SecurityDevelopment Lifecycle, and his most recent release, WritingSecure Code for Windows Vista. 3. C# 3.0:The Complete ReferenceHerbert SchildtNew York Chicago San FranciscoLisbon London Madrid Mexico CityMilan New Delhi San JuanSeoul Singapore Sydney Toronto 4. Copyright 2009 by The McGraw-Hill Companies. All rights reserved. Except as permitted under the United States Copyright Act of 1976,no part of this publication may be reproduced or distributed in any form or by any means, or stored in a database or retrieval system, withoutthe prior written permission of the publisher.ISBN: 978-0-07-159842-2MHID: 0-07-159842-6The material in this eBook also appears in the print version of this title: ISBN: 978-0-07-158841-6, MHID: 0-07-158841-8.All trademarks are trademarks of their respective owners. Rather than put a trademark symbol after every occurrence of a trademarked name,we use names in an editorial fashion only, and to the benefit of the trademark owner, with no intention of infringement of the trademark. Wheresuch designations appear in this book, they have been printed with initial caps.McGraw-Hill eBooks are available at special quantity discounts to use as premiums and sales promotions, or for use in corporate trainingprograms. To contact a representative please visit the Contact Us page at www.mhprofessional.com.Information has been obtained by McGraw-Hill from sources believed to be reliable. However, because of the possibility of human ormechanical error by our sources, McGraw-Hill, or others, McGraw-Hill does not guarantee the accuracy, adequacy, or completeness of anyinformation and is not responsible for any errors or omissions or the results obtained from the use of such information.TERMS OF USEThis is a copyrighted work and The McGraw-Hill Companies, Inc. (McGraw-Hill) and its licensors reserve all rights in and to the work. Useof this work is subject to these terms. Except as permitted under the Copyright Act of 1976 and the right to store and retrieve one copy of thework, you may not decompile, disassemble, reverse engineer, reproduce, modify, create derivative works based upon, transmit, distribute,disseminate, sell, publish or sublicense the work or any part of it without McGraw-Hills prior consent. You may use the work for your ownnoncommercial and personal use; any other use of the work is strictly prohibited. Your right to use the work may be terminated if you fail tocomply with these terms.THE WORK IS PROVIDED AS IS. McGRAW-HILL AND ITS LICENSORS MAKE NO GUARANTEES OR WARRANTIES AS TO THEACCURACY, ADEQUACY OR COMPLETENESS OF OR RESULTS TO BE OBTAINED FROM USING THE WORK, INCLUDING ANYINFORMATION THAT CAN BE ACCESSED THROUGH THE WORK VIA HYPERLINK OR OTHERWISE, AND EXPRESSLY DIS-CLAIMANY WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OFMERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. McGraw-Hill and its licensors do not warrant or guarantee that thefunctions contained in the work will meet your requirements or that its operation will be uninterrupted or error free. Neither McGraw-Hill norits licensors shall be liable to you or anyone else for any inaccuracy, error or omission, regardless of cause, in the work or for any damagesresulting therefrom. McGraw-Hill has no responsibility for the content of any information accessed through the work. Under no circumstancesshall McGraw-Hill and/or its licensors be liable for any indirect, incidental, special, punitive, consequential or similar damages that result fromthe use of or inability to use the work, even if any of them has been advised of the possibility of such damages. This limitation of liability shallapply to any claim or cause whatsoever whether such claim or cause arises in contract, tort or otherwise. 5. Contents at a GlancePart I The C# Language1 The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 An Overview of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Data Types, Literals, and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1378 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1659 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21310 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24511 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26912 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31113 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33714 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36315 Delegates, Events, and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . 39916 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 43717 Runtime Type ID, Refl ection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 45918 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49519 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54520 Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics . . . . . 585Part II Exploring the C# Library21 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61522 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66323 Multithreaded Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70324 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74925 Networking Through the Internet Using System.Net . . . . . . . . . . . . . . . . . 82126 Use System.Windows.Forms to Create Form-Based WindowsApplications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847A Documentation Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . 867Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 871v 6. This page intentionally left blank 7. ContentsSpecial Thanks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiPreface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiiiPart I The C# Language1 The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3C#s Family Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3C: The Beginning of the Modern Age of Programming . . . . . . . . . . . 3The Creation of OOP and C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4The Internet and Java Emerge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5The Evolution of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7How C# Relates to the .NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7What Is the .NET Framework? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8How the Common Language Runtime Works . . . . . . . . . . . . . . . . . . . . . . . . . 8Managed vs. Unmanaged Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9The Common Language Specifi cation . . . . . . . . . . . . . . . . . . . . . . . . . . 92 An Overview of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Object-Oriented Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13A First Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13Using csc.exe, the C# Command-Line Compiler . . . . . . . . . . . . . . . . . 14Using the Visual Studio IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15The First Sample Program, Line by Line . . . . . . . . . . . . . . . . . . . . . . . . 19Handling Syntax Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22A Small Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22A Second Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23Another Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Two Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28Using Code Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29Semicolons, Positioning, and Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31The C# Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32Identifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33The .NET Framework Class Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34vii 8. viii C # 3 . 0 : T h e C o m p l e t e R e f e r e n c e3 Data Types, Literals, and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Why Data Types Are Important . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35C#s Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36Floating-Point Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38The decimal Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41The bool Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42Some Output Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46Hexadecimal Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47Character Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48A Closer Look at Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49Initializing a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50Dynamic Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50Implicitly Typed Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51The Scope and Lifetime of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52Type Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55Automatic Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55Casting Incompatible Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56Type Conversion in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59Using Casts in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63Increment and Decrement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64Relational and Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67Short-Circuit Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70The Assignment Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72The Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73The Bitwise AND, OR, XOR, and NOT Operators . . . . . . . . . . . . . . . 73The Shift Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79Bitwise Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81The ? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82Spacing and Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85Nested ifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86The if-else-if Ladder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88Nested switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92Some Variations on the for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 9. C o n t e n t s ixThe while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99The do-while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102Using break to Exit a Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102Using continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105The goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1056 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109Class Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109The General Form of a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109Defi ne a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110How Objects Are Created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114Reference Variables and Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116Add a Method to the Building Class . . . . . . . . . . . . . . . . . . . . . . . . . . . 117Return from a Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119Return a Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120Use Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122Add a Parameterized Method to Building . . . . . . . . . . . . . . . . . . . . . . 125Avoiding Unreachable Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126Parameterized Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128Add a Constructor to the Building Class . . . . . . . . . . . . . . . . . . . . . . . 129The new Operator Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130Using new with Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130Garbage Collection and Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131The this Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1337 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137One-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141Two-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141Arrays of Three or More Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . 142Initializing Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 143Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144Assigning Array References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146Using the Length Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148Using Length with Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150Implicitly Typed Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156Constructing Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156Operating on Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157Arrays of Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 10. x C # 3 . 0 : T h e C o m p l e t e R e f e r e n c eStrings Are Immutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161Strings Can Be Used in switch Statements . . . . . . . . . . . . . . . . . . . . . . 1628 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165Controlling Access to Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165C#s Access Modifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165Applying Public and Private Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 167Controlling Access: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168Pass References to Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172How Arguments Are Passed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174Use ref and out Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176Use ref . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177Use out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178Use ref and out on References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181Use a Variable Number of Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182Return Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185Return an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187Method Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188Overload Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194Invoke an Overloaded Constructor Through this . . . . . . . . . . . . . . . . 197Object Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199The Main( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200Return Values from Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200Pass Arguments to Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202Understanding static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205Static Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210Static Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2119 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213Operator Overloading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213Overloading Binary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214Overloading Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216Handling Operations on C# Built-in Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 220Overloading the Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224Overloading true and false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226Overloading the Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229A Simple Approach to Overloading the Logical Operators . . . . . . . . 229Enabling the Short-Circuit Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 231Conversion Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235Operator Overloading Tips and Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . 239Another Example of Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . 24010 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245Creating One-Dimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . 245Indexers Can Be Overloaded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 11. C o n t e n t s xiIndexers Do Not Require an Underlying Array . . . . . . . . . . . . . . . . . . 251Multidimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254Auto-Implemented Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259Use Object Initializers with Properties . . . . . . . . . . . . . . . . . . . . . . . . . 260Property Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261Use Access Modifi ers with Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261Using Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26411 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269Inheritance Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269Member Access and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272Using Protected Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275Constructors and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276Calling Base Class Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278Inheritance and Name Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282Using base to Access a Hidden Name . . . . . . . . . . . . . . . . . . . . . . . . . . 283Creating a Multilevel Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285When Are Constructors Called? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288Base Class References and Derived Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 289Virtual Methods and Overriding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294Why Overridden Methods? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297Applying Virtual Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298Using Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301Using sealed to Prevent Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305The object Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305Boxing and Unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307Is object a Universal Data Type? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30912 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311Implementing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312Using Interface References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316Interface Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318Interface Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320Interfaces Can Be Inherited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322Name Hiding with Interface Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323Explicit Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323Choosing Between an Interface and an Abstract Class . . . . . . . . . . . . . . . . . . 326The .NET Standard Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326Why Structures? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332Initialize an Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333Specify the Underlying Type of an Enumeration . . . . . . . . . . . . . . . . 334Use Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 12. xii C # 3 . 0 : T h e C o m p l e t e R e f e r e n c e13 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337The System.Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337Exception Handling Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338Using try and catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338A Simple Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338A Second Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340The Consequences of an Uncaught Exception . . . . . . . . . . . . . . . . . . . . . . . . . 341Exceptions Let You Handle Errors Gracefully . . . . . . . . . . . . . . . . . . . . . . . . . 343Using Multiple catch Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344Catching All Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345Nesting try Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346Throwing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347Rethrowing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348Using fi nally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349A Closer Look at the Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351Commonly Used Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352Deriving Exception Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354Catching Derived Class Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358Using checked and unchecked . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36014 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363C#s I/O Is Built Upon Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363Byte Streams and Character Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . 363The Predefi ned Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363The Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364The Stream Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364The Byte Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365The Character Stream Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . 365Binary Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367Console I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367Reading Console Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367Using ReadKey( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369Writing Console Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371FileStream and Byte-Oriented File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371Opening and Closing a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372Reading Bytes from a FileStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374Writing to a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375Using FileStream to Copy a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376Character-Based File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378Using StreamWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378Using a StreamReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380Redirecting the Standard Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381Reading and Writing Binary Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383BinaryWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383BinaryReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384Demonstrating Binary I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 13. C o n t e n t s xiiiRandom Access Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390Using MemoryStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392Using StringReader and StringWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394Converting Numeric Strings to Their Internal Representation . . . . . . . . . . . 39615 Delegates, Events, and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . 399Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399Delegate Method Group Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . 402Using Instance Methods as Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . 402Multicasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404Covariance and Contravariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406System.Delegate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408Why Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408Anonymous Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408Anonymous Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409Pass Arguments to an Anonymous Method . . . . . . . . . . . . . . . . . . . . . 410Return a Value from an Anonymous Method . . . . . . . . . . . . . . . . . . . 410Use Outer Variables with Anonymous Methods . . . . . . . . . . . . . . . . . 412Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413The Lambda Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413Expression Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414Statement Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419A Multicast Event Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421Instance Methods vs. Static Methods as Event Handlers . . . . . . . . . . 422Using Event Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424Miscellaneous Event Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429Use Anonymous Methods and Lambda Expressions with Events . . . . . . . . 429.NET Event Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430Use EventHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432Applying Events: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43316 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 437Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437Declaring a Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438Namespaces Prevent Name Confl icts . . . . . . . . . . . . . . . . . . . . . . . . . . 440using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441A Second Form of using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443Namespaces Are Additive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444Namespaces Can Be Nested . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446The Global Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447Using the :: Namespace Alias Qualifi er . . . . . . . . . . . . . . . . . . . . . . . . 447The Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451#defi ne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452#if and #endif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452#else and #elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454#undef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455 14. xiv C # 3 . 0 : T h e C o m p l e t e R e f e r e n c e#error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456#warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456#line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456#region and #endregion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456#pragma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457Assemblies and the internal Access Modifi er . . . . . . . . . . . . . . . . . . . . . . . . . 457The internal Access Modifi er . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45817 Runtime Type ID, Refl ection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 459Runtime Type Identifi cation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459Testing a Type with is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459Using as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460Using typeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462Refl ection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463The Refl ection Core: System.Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463Using Refl ection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465Obtaining Information About Methods . . . . . . . . . . . . . . . . . . . . . . . . 465Calling Methods Using Refl ection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469Obtaining a Types Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471Obtaining Types from Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475Fully Automating Type Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483Attribute Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483Positional vs. Named Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487Three Built-in Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491AttributeUsage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491The Conditional Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491The Obsolete Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49318 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495What Are Generics? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495A Simple Generics Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496Generic Types Differ Based on Their Type Arguments . . . . . . . . . . . . 499How Generics Improve Type Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . 499A Generic Class with Two Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 502The General Form of a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503Constrained Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503Using a Base Class Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504Using an Interface Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512Using the new( ) Constructor Constraint . . . . . . . . . . . . . . . . . . . . . . . 516The Reference Type and Value Type Constraints . . . . . . . . . . . . . . . . 517Using a Constraint to Establish a Relationship Between Two TypeParameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520Using Multiple Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521Creating a Default Value of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . 522Generic Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523Creating a Generic Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 15. C o n t e n t s xvUsing Explicit Type Arguments to Call a Generic Method . . . . . . . . 527Using a Constraint with a Generic Method . . . . . . . . . . . . . . . . . . . . . 527Generic Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530Comparing Instances of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534Generic Class Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537Using a Generic Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537A Generic Derived Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539Overriding Virtual Methods in a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . 540Overloading Methods That Use Type Parameters . . . . . . . . . . . . . . . . . . . . . 542How Generic Types Are Instantiated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543Some Generic Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544Final Thoughts on Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54419 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545What Is LINQ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545LINQ Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546A Simple Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546A Query Can Be Executed More Than Once . . . . . . . . . . . . . . . . . . . . 548How the Data Types in a Query Relate . . . . . . . . . . . . . . . . . . . . . . . . . 549The General Form of a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550Filter Values with where . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551Sort Results with orderby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552A Closer Look at select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556Use Nested from Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560Group Results with group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561Use into to Create a Continuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563Use let to Create a Variable in a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565Join Two Sequences with join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566Anonymous Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569Create a Group Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571The Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574The Basic Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574Create Queries by Using the Query Methods . . . . . . . . . . . . . . . . . . . 575Query Syntax vs. Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577More Query-Related Extension Methods . . . . . . . . . . . . . . . . . . . . . . . 577Deferred vs. Immediate Query Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580Expression Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58220 Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics . . . . . 585Unsafe Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585Pointer Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586Using unsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587Using fi xed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588Accessing Structure Members Through a Pointer . . . . . . . . . . . . . . . . 589 16. xvi C # 3 . 0 : T h e C o m p l e t e R e f e r e n c ePointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589Pointer Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591Pointers and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591Pointers and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593Multiple Indirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594Arrays of Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595stackalloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596Creating Fixed-Size Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598Nullable Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598Nullable Objects in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600The ?? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601Nullable Objects and the Relational and Logical Operators . . . . . . . 602Partial Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603Partial Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604Friend Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605Miscellaneous Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605readonly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606const and volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607The using Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608Part II Exploring the C# Library21 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615The Members of System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615The Math Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617The .NET Structures Corresponding to the Built-in Value Types . . . . . . . . . 623The Integer Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623The Floating-Point Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630Char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634The Boolean Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640The Array Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641Sorting and Searching Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648Reversing an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650Copying an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651Using a Predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652Using an Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653BitConverter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654Generating Random Numbers with Random . . . . . . . . . . . . . . . . . . . . . . . . . 656Memory Management and the GC Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659The IComparable and IComparable Interfaces . . . . . . . . . . . . . . . . . . . . . 659The IEquatable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660 17. C o n t e n t s xviiThe IConvertible Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660The ICloneable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660IFormatProvider and IFormattable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66222 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663Strings in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663The String Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664The String Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664The String Field, Indexer, and Property . . . . . . . . . . . . . . . . . . . . . . . . 665The String Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665The String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665Padding and Trimming Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681Inserting, Removing, and Replacing . . . . . . . . . . . . . . . . . . . . . . . . . . . 682Changing Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683Using the Substring( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684The String Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684Formatting Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685The Numeric Format Specifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686Understanding Argument Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 687Using String.Format( ) and ToString( ) to Format Data . . . . . . . . . . . . . . . . . 688Using String.Format( ) to Format Values . . . . . . . . . . . . . . . . . . . . . . . 688Using ToString( ) to Format Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691Creating a Custom Numeric Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692The Custom Format Placeholder Characters . . . . . . . . . . . . . . . . . . . . 692Formatting Date and Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695Creating a Custom Date and Time Format . . . . . . . . . . . . . . . . . . . . . . 698Formatting Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70023 Multithreaded Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703Multithreading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703The Thread Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704Creating and Starting a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704Some Simple Improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707Creating Multiple Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708Determining When a Thread Ends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710Passing an Argument to a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713The IsBackground Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715Thread Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717An Alternative Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721The Monitor Class and lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723Thread Communication Using Wait( ), Pulse( ), and PulseAll( ) . . . . . . . . . 723An Example That Uses Wait( ) and Pulse( ) . . . . . . . . . . . . . . . . . . . . . 724Deadlock and Race Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727Using MethodImplAttribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728Using a Mutex and a Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 18. xviii C # 3 . 0 : T h e C o m p l e t e R e f e r e n c eThe Mutex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730The Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734Using Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737The Interlocked Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739Terminating a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741An Abort( ) Alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742Canceling Abort( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743Suspending and Resuming a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745Determining a Threads State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745Using the Main Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 746Multithreading Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747Starting a Separate Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74724 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749Collections Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749The Non-Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750The Non-Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751The DictionaryEntry Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 755The Non-Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 755Storing Bits with BitArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771The Specialized Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774The Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774The Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775The KeyValuePair Structure . . . . . . . . . . . . . . . . . . . . . . . . . 778The Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779Storing User-Defi ned Classes in Collections . . . . . . . . . . . . . . . . . . . . . . . . . . 799Implementing IComparable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801Implementing IComparable for Non-Generic Collections . . . . . . . . . 802Implementing IComparable for Generic Collections . . . . . . . . . . 803Using an IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805Using a Non-Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805Using a Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806Accessing a Collection via an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808Using an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808Using the IDictionaryEnumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809Implementing IEnumerable and IEnumerator . . . . . . . . . . . . . . . . . . . . . . . . 811Using Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 813Stopping an Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 815Using Multiple yield Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 815Creating a Named Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816Creating a Generic Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 818Collection Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81925 Networking Through the Internet Using System.Net . . . . . . . . . . . . . . . . . 821The System.Net Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821Uniform Resource Identifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 19. C o n t e n t s xixInternet Access Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823WebRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824WebResponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826HttpWebRequest and HttpWebResponse . . . . . . . . . . . . . . . . . . . . . . . 826A Simple First Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827Handling Network Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830Exceptions Generated by Create( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830Exceptions Generated by GetReponse( ) . . . . . . . . . . . . . . . . . . . . . . . . 830Exceptions Generated by GetResponseStream( ) . . . . . . . . . . . . . . . . . 831Using Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 831The Uri Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833Accessing Additional HTTP Response Information . . . . . . . . . . . . . . . . . . . . 834Accessing the Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834Accessing Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836Using the LastModifi ed Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838MiniCrawler: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839Using WebClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84226 Use System.Windows.Forms to Create Form-BasedWindows Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847A Brief History of Windows Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . 847Two Ways to Write a Form-Based Windows Application . . . . . . . . . . . . . . . 848How Windows Interacts with the User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848Windows Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849The Form Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849A Skeletal Form-Based Windows Program . . . . . . . . . . . . . . . . . . . . . . . . . . . 849Compiling the Windows Skeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851Adding a Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852Button Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852Adding a Button to a Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852A Simple Button Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853Handling Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853An Alternative Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856Using a Message Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856Adding a Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 859Creating a Traditional-Style Main Menu . . . . . . . . . . . . . . . . . . . . . . . 859Creating a New-Style Menu with MenuStrip . . . . . . . . . . . . . . . . . . . 863A Documentation Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . 867The XML Comment Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867Compiling Documentation Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 868An XML Documentation Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 871 20. This page intentionally left blank 21. Special ThanksSpecial thanks go to Michael Howard for his excellent technical edit of this book. Hisexpertise, insights, suggestions, and advice were of great value.xxi 22. This page intentionally left blank 23. PrefaceWe programmers are a demanding bunch, always looking for ways to improve theperformance, efficiency, and portability of our programs. We also demand muchfrom the tools we use, especially when it comes to programming languages.There are many programming languages, but only a few are great. A great programminglanguage must be powerful, yet flexible. Its syntax must be terse, but clear. It must facilitatethe creation of correct code while not getting in our way. It must support state-of-the-artfeatures, but not trendy dead ends. Finally, a great programming language must have onemore, almost intangible quality: It must feel right when we use it. C# is such a language.Created by Microsoft to support its .NET Framework, C# builds on a rich programmingheritage. Its chief architect was long-time programming guru Anders Hejlsberg. C# isdirectly descended from two of the worlds most successful computer languages: C andC++. From C, it derives its syntax, many of its keywords, and its operators. It builds uponand improves the object model defined by C++. C# is also closely related to another verysuccessful language: Java.Sharing a common ancestry, but differing in many important ways, C# and Java aremore like cousins. Both support distributed programming and both use intermediate codeto achieve safety and portability, but the details differ. They both also provide a significantamount of runtime error checking, security, and managed execution, but again, the detailsdiffer. However, unlike Java, C# also gives you access to pointersa feature supported byC++. Thus, C# combines the raw power of C++ with the type safety of Java. Furthermore,the trade-offs between power and safety are carefully balanced and are nearly transparent.Throughout the history of computing, programming languages have evolved toaccommodate changes in the computing environment, advances in computer language theory,and new ways of thinking about and approaching the job of programming. C# is no exception.In the ongoing process of refinement, adaptation, and innovation, C# has demonstrated itsability to respond rapidly to the changing needs of the programmer. This fact is testified toby the many new features added to C# since its initial 1.0 release in 2000.Consider the first major revision, C# 2.0. It added several features that made it easier forprogrammers to write more resilient, reliable, and nimble code. Without question, the mostimportant 2.0 addition was generics. Through the use of generics, it became possible to createtype-safe, reusable code in C#. Thus, the addition of generics fundamentally expanded thepower and scope of the language.Now consider the second major revision, C# 3.0. This is the latest version of C# and is theversion described in this book. It is not an exaggeration to say that C# 3.0 has added featuresthat have redefined the very core of C#, raising the bar in computer language development inthe process. Of its many innovative features, two stand out: LINQ and lambda expressions.LINQ, which stands for Language Integrated Query, enables you to create database-stylequeries by using elements of the C# language. Lambda expressions implement a functional-stylesyntax that uses the => lambda operator, and lambda expressions are frequently used inLINQ expressions.As you will see in the course of this book, the combination of LINQ and lambda expressionsrepresents a radically powerful subset of C#. Furthermore, they are revolutionary features thatxxiii 24. xxiv C # 3 . 0 : T h e C o m p l e t e R e f e r e n c eare redefining how solutions are crafted for many different types of programming tasks, not justdatabase queries. In essence, they let you approach old problems in new ways. Their use notonly streamlines a solution, but also helps you conceptualize a problem from a different pointof view. Simply put, the addition of LINQ and lambda expressions is both significant and farreaching. They are changing the way we think about the job of programming.Because of its ability to adapt rapidly to the changing demands of the programminglandscape, C# has remained a vibrant and innovative language. As a result, it defines oneof the most powerful, feature-rich languages in modern computing. It is also a languagethat no programmer can afford to ignore. This book is designed to help you master it.Whats InsideThis book describes C# 3.0. It is divided into two parts. Part I provides a comprehensivediscussion of the C# language, including the new features added by version 3.0. This is thelargest part in the book, and it describes the keywords, syntax, and features that define thelanguage. I/O, file handling, reflection, and the preprocessor are also discussed in Part I.Part II explores the C# class library, which is the .NET Framework class library. Thislibrary is huge! Because of space limitations, it is not possible to cover the entire .NETFramework class library in one book. Instead, Part II focuses on the core library, which iscontained in the System namespace. Also covered are collections, multithreading,networking, and Windows Forms. These are the parts of the library that nearly every C#programmer will use.A Book for All ProgrammersThis book does not require any previous programming experience. If you already knowC++ or Java, you will be able to advance quite rapidly because C# has much in commonwith those languages. If you dont have any previous programming experience, you willstill be able to learn C# from this book, but you will need to work carefully through theexamples in each chapter.Required SoftwareTo compile and run C# 3.0 programs, you must use Visual Studio 2008 or later.Dont Forget: Code on the WebRemember, the source code for all of the programs in this book is available free-of-charge onthe Web at www.mhprofessional.com. 25. For Further StudyC# 3.0: The Complete Reference is your gateway to the Herb Schildt series of programmingbooks. Here are some others that you will find of interest.For a carefully paced introduction to C#, tryC# 3.0: A Beginners GuideTo learn about Java programming, we recommend the following:Java: The Complete ReferenceJava: A Beginners GuideSwing: A Beginners GuideThe Art of JavaHerb Schildts Java Programming CookbookTo learn about C++, you will find these books especially helpful:C++: The Complete ReferenceC++: A Beginners GuideC++ From the Ground UpSTL Programming From the Ground UpThe Art of C++Herb Schildts C++ Programming CookbookIf you want to learn about the C language, the foundation of all modern programming, thefollowing title will be of interest:C: The Complete ReferenceWhen you need solid answers, fast, turn to Herbert Schildt,the recognized authority on programming.P r e f a c e xxv 26. This page intentionally left blank 27. IThe C# LanguagePart I discusses the elements of the C# language, including itskeywords, syntax, and operators. Also described are severalfoundational C# techniques, such as using I/O and reflection,which are tightly linked with the C# language.PARTCHAPTER 1The Creation of C#CHAPTER 2An Overview of C#CHAPTER 3Data Types, Literals, and VariablesCHAPTER 4OperatorsCHAPTER 5Program Control StatementsCHAPTER 6Introducing Classes and ObjectsCHAPTER 7Arrays and StringsCHAPTER 8A Closer Look at Methods and ClassesCHAPTER 9Operator OverloadingCHAPTER 10Indexers and PropertiesCHAPTER 11InheritanceCHAPTER 12Interfaces, Structures, and EnumerationsCHAPTER 13Exception HandlingCHAPTER 14Using I/OCHAPTER 15Delegates, Events, and LambdaExpressionsCHAPTER 16Namespaces, the Preprocessor, andAssembliesCHAPTER 17Runtime Type ID, Refl ection, andAttributesCHAPTER 18GenericsCHAPTER 19LINQCHAPTER 20Unsafe Code, Pointers, Nullable Types,and Miscellaneous Topics 28. This page intentionally left blank 29. 1CHAPTERThe Creation of C#C# is Microsofts premier language for .NET development. It leverages time-testedfeatures with cutting-edge innovations and provides a highly usable, efficient wayto write programs for the modern enterprise computing environment. It is, by anymeasure, one of the most important languages of the 21st century.The purpose of this chapter is to place C# into its historical context, including the forcesthat drove its creation, its design philosophy, and how it was influenced by other computerlanguages. This chapter also explains how C# relates to the .NET Framework. As you willsee, C# and the .NET Framework work together to create a highly refined programmingenvironment.C#s Family TreeComputer languages do not exist in a void. Rather, they relate to one another, with each newlanguage influenced in one form or another by the ones that came before. In a process akin tocross-pollination, features from one language are adapted by another, a new innovation isintegrated into an existing context, or an older construct is removed. In this way, languagesevolve and the art of programming advances. C# is no exception.C# inherits a rich programming legacy. It is directly descended from two of the worldsmost successful computer languages: C and C++. It is closely related to another: Java.Understanding the nature of these relationships is crucial to understanding C#. Thus, webegin our examination of C# by placing it in the historical context of these three languages.C: The Beginning of the Modern Age of ProgrammingThe creation of C marks the beginning of the modern age of programming. C was inventedby Dennis Ritchie in the 1970s on a DEC PDP-11 that used the UNIX operating system.While some earlier languages, most notably Pascal, had achieved significant success, Cestablished the paradigm that still charts the course of programming today.C grew out of the structured programming revolution of the 1960s. Prior to structuredprogramming, large programs were difficult to write because the program logic tended todegenerate into what is known as spaghetti code, a tangled mass of jumps, calls, andreturns that is difficult to follow. Structured languages addressed this problem by addingwell-defined control statements, subroutines with local variables, and other improvements.Through the use of structured techniques programs became better organized, more reliable,and easier to manage.3 30. 4 P a r t I : T h e C # L a n g u a g eAlthough there were other structured languages at the time, C was the first to successfullycombine power, elegance, and expressiveness. Its terse, yet easy-to-use syntax coupled withits philosophy that the programmer (not the language) was in charge quickly won manyconverts. It can be a bit hard to understand from todays perspective, but C was a breath offresh air that programmers had long awaited. As a result, C became the most widely usedstructured programming language of the 1980s.However, even the venerable C language had its limits. One of the most troublesomewas its inability to handle large programs. The C language hits a barrier once a projectreaches a certain size, and after that point, C programs are difficult to understand andmaintain. Precisely where this limit is reached depends upon the program, the programmer,and the tools at hand, but there is always a threshold beyond which a C program becomesunmanageable.The Creation of OOP and C++By the late 1970s, the size of many projects was near or at the limits of what structuredprogramming methodologies and the C language could handle. To solve this problem, anew way to program began to emerge. This method is called object-oriented programming(OOP). Using OOP, a programmer could handle much larger programs. The trouble wasthat C, the most popular language at the time, did not support object-oriented programming.The desire for an object-oriented version of C ultimately led to the creation of C++.C++ was invented by Bjarne Stroustrup beginning in 1979 at Bell Laboratories in MurrayHill, New Jersey. He initially called the new language C with Classes. However, in 1983 thename was changed to C++. C++ contains the entire C language. Thus, C is the foundationupon which C++ is built. Most of the additions that Stroustrup made to C were designed tosupport object-oriented programming. In essence, C++ is the object-oriented version of C. Bybuilding upon the foundation of C, Stroustrup provided a smooth migration path to OOP.Instead of having to learn an entirely new language, a C programmer needed to learn onlya few new features before reaping the benefits of the object-oriented methodology.C++ simmered in the background during much of the 1980s, undergoing extensivedevelopment. By the beginning of the 1990s, C++ was ready for mainstream use, and itspopularity exploded. By the end of the decade, it had become the most widely usedprogramming language. Today, C++ is still the preeminent language for the development ofhigh-performance system code.It is critical to understand that the invention of C++ was not an attempt to create anentirely new programming language. Instead, it was an enhancement to an already highlysuccessful language. This approach to language developmentbeginning with an existinglanguage and moving it forwardestablished a trend that continues today.The Internet and Java EmergeThe next major advance in programming languages is Java. Work on Java, which wasoriginally called Oak, began in 1991 at Sun Microsystems. The main driving force behindJavas design was James Gosling. Patrick Naughton, Chris Warth, Ed Frank, and MikeSheridan also played a role.Java is a structured, object-oriented language with a syntax and philosophy derived fromC++. The innovative aspects of Java were driven not so much by advances in the art ofprogramming (although some certainly were), but rather by changes in the computingenvironment. Prior to the mainstreaming of the Internet, most programs were written, 31. PART IC h a p t e r 1 : T h e C r e a t i o n o f C # 5compiled, and targeted for a specific CPU and a specific operating system. While it has alwaysbeen true that programmers like to reuse their code, the ability to port a program easily fromone environment to another took a backseat to more pressing problems. However, with therise of the Internet, in which many different types of CPUs and operating systems areconnected, the old problem of portability reemerged with a vengeance. To solve the problemof portability, a new language was needed, and this new language was Java.Although the single most important aspect of Java (and the reason for its rapid acceptance)is its ability to create cross-platform, portable code, it is interesting to note that the originalimpetus for Java was not the Internet, but rather the need for a platform-independentlanguage that could be used to create software for embedded controllers. In 1993, it becameclear that the issues of cross-platform portability found when creating code for embeddedcontrollers are also encountered when attempting to create code for the Internet. Remember:the Internet is a vast, distributed computing universe in which many different types ofcomputers live. The same techniques that solved the portability problem on a small scalecould be applied to the Internet on a large scale.Java achieved portability by translating a programs source code into an intermediatelanguage called bytecode. This bytecode was then executed by the Java Virtual Machine(JVM). Therefore, a Java program could run in any environment for which a JVM wasavailable. Also, since the JVM is relatively easy to implement, it was readily available fora large number of environments.Javas use of bytecode differed radically from both C and C++, which were nearlyalways compiled to executable machine code. Machine code is tied to a specific CPU andoperating system. Thus, if you wanted to run a C/C++ program on a different system, itneeded to be recompiled to machine code specifically for that environment. Therefore, tocreate a C/C++ program that would run in a variety of environments, several differentexecutable versions of the program would be needed. Not only was this impractical, it wasexpensive. Javas use of an intermediate language was an elegant, cost-effective solution.It is also a solution that C# would adapt for its own purposes.As mentioned, Java is descended from C and C++. Its syntax is based on C, and its objectmodel is evolved from C++. Although Java code is neither upwardly nor downwardlycompatible with C or C++, its syntax is sufficiently similar that the large pool of existingC/C++ programmers could move to Java with very little effort. Furthermore, because Javabuilt upon and improved an existing paradigm, Gosling, et al., were free to focus theirattention on the new and innovative features. Just as Stroustrup did not need to reinventthe wheel when creating C++, Gosling did not need to create an entirely new languagewhen developing Java. Moreover, with the creation of Java, C and C++ became an acceptedsubstrata upon which to base a new computer language.The Creation of C#While Java has successfully addressed many of the issues surrounding portability in theInternet environment, there are still features that it lacks. One is cross-language interoperability,also called mixed-language programming. This is the ability for the code produced by onelanguage to work easily with the code produced by another. Cross-language interoperabilityis needed for the creation of large, distributed software systems. It is also desirable forprogramming software components because the most valuable component is one that canbe used by the widest variety of computer languages, in the greatest number of operatingenvironments. 32. 6 P a r t I : T h e C # L a n g u a g eAnother feature lacking in Java is full integration with the Windows platform. AlthoughJava programs can be executed in a Windows environment (assuming that the Java VirtualMachine has been installed), Java and Windows are not closely coupled. Since Windows isthe most widely used operating system in the world, lack of direct support for Windows is adrawback to Java.To answer these and other needs, Microsoft developed C#. C# was created at Microsoftlate in the 1990s and was part of Microsofts overall .NET strategy. It was first released in itsalpha version in the middle of 2000. C#s chief architect was Anders Hejlsberg. Hejlsberg isone of the worlds leading language experts, with several notable accomplishments to hiscredit. For example, in the 1980s he was the original author of the highly successful andinfluential Turbo Pascal, whose streamlined implementation set the standard for all futurecompilers.C# is directly related to C, C++, and Java. This is not by accident. These are three ofthe most widely usedand most widely likedprogramming languages in the world.Furthermore, at the time of C#s creation, nearly all professional programmers knew C, C++,and/or Java. By building C# upon a solid, well-understood foundation, C# offered an easymigration path from these languages. Since it was neither necessary nor desirable for Hejlsbergto reinvent the wheel, he was free to focus on specific improvements and innovations.The family tree for C# is shown in Figure 1-1. The grandfather of C# is C. From C, C#derives its syntax, many of its keywords, and its operators. C# builds upon and improvesthe object model defined by C++. If you know C or C++, then you will feel at home with C#.C# and Java have a bit more complicated relationship. As explained, Java is alsodescended from C and C++. It too shares the C/C++ syntax and object model. Like Java, C#is designed to produce portable code. However, C# is not descended from Java. Instead, C#and Java are more like cousins, sharing a common ancestry, but differing in many importantways. The good news, though, is that if you know Java, then many C# concepts will befamiliar. Conversely, if in the future you need to learn Java, then many of the things youlearn about C# will carry over.C# contains many innovative features that we will examine at length throughout thecourse of this book, but some of its most important relate to its built-in support for softwarecomponents. In fact, C# has been characterized as being a component-oriented languagebecause it contains integral support for the writing of software components. For example,FIGURE 1-1The C# family tree 33. PART IC h a p t e r 1 : T h e C r e a t i o n o f C # 7C# includes features that directly support the constituents of components, such asproperties, methods, and events. However, C#s ability to work in a secure, mixed-languageenvironment is perhaps its most important component-oriented feature.The Evolution of C#Since its original 1.0 release, C# has been evolving at a rapid pace. Not long after C# 1.0,Microsoft released version 1.1. It contained many minor tweaks but added no majorfeatures. However, the situation was much different with the release of C# 2.0.C# 2.0 was a watershed event in the lifecycle of C# because it added many new features,such as generics, partial types, and anonymous methods, that fundamentally expandedthe scope, power, and range of the language. Version 2.0 firmly put C# at the forefront ofcomputer language development. It also demonstrated Microsofts long-term commitmentto the language.The next major release of C# was 3.0, and this is the version of C# describe