c# 3.0 the complete reference - herbert schildt

913

Upload: hussain-amravatiwala

Post on 10-May-2015

1.391 views

Category:

Technology


13 download

TRANSCRIPT

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

2. About the Author Herbert Schildt is a leading authority on C#, C++, C, and Java. His programming books have sold more than 3.5 million copies worldwide and have been translated into all major foreign languages. He is the author of numerous bestsellers, including Java: The Complete Reference, C++: The Complete Reference, C: The Complete Reference, and C#: A Beginners Guide. Although interested in all facets of computing, his primary focus is computer languages, including compilers, interpreters, and robotic control languages. He also has an active interest in the standardization of languages. Schildt holds both graduate and 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 Editor Michael Howard (Austin, Texas) is a principal security program 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 the company. Howard is an architect of the Security Development Lifecycle (SDL), a process for improving the security of Microsofts software. Howard speaks regularly on the topic of securing code for Microsoft and at conferences worldwide. He regularly publishes articles on security design and is the co-author of six security books, including the award-winning Writing Secure Code, 19 Deadly Sins of Software Security, The Security Development Lifecycle, and his most recent release, Writing Secure Code for Windows Vista. 3. C# 3.0: The Complete Reference Herbert Schildt New York Chicago San Francisco Lisbon London Madrid Mexico City Milan New Delhi San Juan Seoul 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, without the prior written permission of the publisher. ISBN: 978-0-07-159842-2 MHID: 0-07-159842-6 The 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. Where such 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 training programs. 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 or mechanical error by our sources, McGraw-Hill, or others, McGraw-Hill does not guarantee the accuracy, adequacy, or completeness of any information and is not responsible for any errors or omissions or the results obtained from the use of such information. TERMS OF USE This is a copyrighted work and The McGraw-Hill Companies, Inc. (McGraw-Hill) and its licensors reserve all rights in and to the work. Use of 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 the work, 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 own noncommercial and personal use; any other use of the work is strictly prohibited. Your right to use the work may be terminated if you fail to comply with these terms. THE WORK IS PROVIDED AS IS. McGRAW-HILL AND ITS LICENSORS MAKE NO GUARANTEES OR WARRANTIES AS TO THE ACCURACY, ADEQUACY OR COMPLETENESS OF OR RESULTS TO BE OBTAINED FROM USING THE WORK, INCLUDING ANY INFORMATION THAT CAN BE ACCESSED THROUGH THE WORK VIA HYPERLINK OR OTHERWISE, AND EXPRESSLY DIS- CLAIM ANY WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. McGraw-Hill and its licensors do not warrant or guarantee that the functions contained in the work will meet your requirements or that its operation will be uninterrupted or error free. Neither McGraw-Hill nor its licensors shall be liable to you or anyone else for any inaccuracy, error or omission, regardless of cause, in the work or for any damages resulting therefrom. McGraw-Hill has no responsibility for the content of any information accessed through the work. Under no circumstances shall McGraw-Hill and/or its licensors be liable for any indirect, incidental, special, punitive, consequential or similar damages that result from the 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 shall apply to any claim or cause whatsoever whether such claim or cause arises in contract, tort or otherwise. 5. Contents at a Glance Part I The C# Language 1 The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2 An Overview of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3 Data Types, Literals, and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 6 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 7 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 8 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 9 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 10 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 11 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 12 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 13 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 14 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 15 Delegates, Events, and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . 399 16 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 437 17 Runtime Type ID, Reection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 459 18 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 19 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 20 Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics . . . . . 585 Part II Exploring the C# Library 21 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615 22 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 23 Multithreaded Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 24 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749 25 Networking Through the Internet Using System.Net . . . . . . . . . . . . . . . . . 821 26 Use System.Windows.Forms to Create Form-Based Windows Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847 A Documentation Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . 867 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 871 v 6. This page intentionally left blank 7. Contents Special Thanks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii Part I The C# Language 1 The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 C#s Family Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 C: The Beginning of the Modern Age of Programming . . . . . . . . . . . 3 The Creation of OOP and C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 The Internet and Java Emerge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 The Evolution of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 How C# Relates to the .NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 What Is the .NET Framework? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 How the Common Language Runtime Works . . . . . . . . . . . . . . . . . . . . . . . . . 8 Managed vs. Unmanaged Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 The Common Language Specication . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2 An Overview of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Object-Oriented Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 A First Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Using csc.exe, the C# Command-Line Compiler . . . . . . . . . . . . . . . . . 14 Using the Visual Studio IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 The First Sample Program, Line by Line . . . . . . . . . . . . . . . . . . . . . . . . 19 Handling Syntax Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 A Small Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 A Second Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Another Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Two Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Using Code Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Semicolons, Positioning, and Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 The C# Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Identiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 The .NET Framework Class Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 vii 8. viii C # 3 . 0 : T h e C o m p l e t e R e f e r e n c e 3 Data Types, Literals, and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Why Data Types Are Important . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 C#s Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Floating-Point Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 The decimal Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 The bool Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Some Output Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Hexadecimal Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Character Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 A Closer Look at Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Initializing a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Dynamic Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Implicitly Typed Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 The Scope and Lifetime of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Type Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Automatic Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Casting Incompatible Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Type Conversion in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Using Casts in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 4 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Increment and Decrement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Relational and Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Short-Circuit Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 The Assignment Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 The Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 The Bitwise AND, OR, XOR, and NOT Operators . . . . . . . . . . . . . . . 73 The Shift Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Bitwise Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 The ? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Spacing and Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Nested ifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 The if-else-if Ladder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Nested switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Some Variations on the for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 9. C o n t e n t s ix The while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 The do-while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Using break to Exit a Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Using continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 The goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Class Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 The General Form of a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Dene a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 How Objects Are Created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Reference Variables and Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Add a Method to the Building Class . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Return from a Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Return a Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Use Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Add a Parameterized Method to Building . . . . . . . . . . . . . . . . . . . . . . 125 Avoiding Unreachable Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Parameterized Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Add a Constructor to the Building Class . . . . . . . . . . . . . . . . . . . . . . . 129 The new Operator Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Using new with Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Garbage Collection and Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 The this Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 7 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 One-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Two-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Arrays of Three or More Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Initializing Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Assigning Array References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Using the Length Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Using Length with Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Implicitly Typed Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Constructing Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Operating on Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Arrays 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 e Strings Are Immutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Strings Can Be Used in switch Statements . . . . . . . . . . . . . . . . . . . . . . 162 8 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Controlling Access to Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 C#s Access Modiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Applying Public and Private Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Controlling Access: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Pass References to Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 How Arguments Are Passed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Use ref and out Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Use ref . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Use out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Use ref and out on References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Use a Variable Number of Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Return Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Return an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Method Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Overload Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Invoke an Overloaded Constructor Through this . . . . . . . . . . . . . . . . 197 Object Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 The Main( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Return Values from Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Pass Arguments to Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Understanding static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Static Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 Static Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 9 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Operator Overloading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Overloading Binary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Overloading Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 Handling Operations on C# Built-in Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Overloading the Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Overloading true and false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Overloading the Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 A Simple Approach to Overloading the Logical Operators . . . . . . . . 229 Enabling the Short-Circuit Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 231 Conversion Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Operator Overloading Tips and Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Another Example of Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 10 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Creating One-Dimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Indexers Can Be Overloaded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 11. C o n t e n t s xi Indexers Do Not Require an Underlying Array . . . . . . . . . . . . . . . . . . 251 Multidimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 Auto-Implemented Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Use Object Initializers with Properties . . . . . . . . . . . . . . . . . . . . . . . . . 260 Property Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Use Access Modiers with Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Using Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 11 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Inheritance Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Member Access and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 Using Protected Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 Constructors and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 Calling Base Class Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Inheritance and Name Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Using base to Access a Hidden Name . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Creating a Multilevel Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 When Are Constructors Called? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 Base Class References and Derived Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 Virtual Methods and Overriding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 Why Overridden Methods? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Applying Virtual Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Using Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 Using sealed to Prevent Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 The object Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 Boxing and Unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 Is object a Universal Data Type? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 12 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 Implementing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 Using Interface References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 Interface Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Interface Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 Interfaces Can Be Inherited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 Name Hiding with Interface Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Explicit Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Choosing Between an Interface and an Abstract Class . . . . . . . . . . . . . . . . . . 326 The .NET Standard Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Why Structures? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 Initialize an Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 Specify the Underlying Type of an Enumeration . . . . . . . . . . . . . . . . 334 Use 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 e 13 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 The System.Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Exception Handling Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Using try and catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 A Simple Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 A Second Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340 The Consequences of an Uncaught Exception . . . . . . . . . . . . . . . . . . . . . . . . . 341 Exceptions Let You Handle Errors Gracefully . . . . . . . . . . . . . . . . . . . . . . . . . 343 Using Multiple catch Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 Catching All Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 Nesting try Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Throwing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 Rethrowing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Using nally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 A Closer Look at the Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351 Commonly Used Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Deriving Exception Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Catching Derived Class Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Using checked and unchecked . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 14 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 C#s I/O Is Built Upon Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 Byte Streams and Character Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 The Predened Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 The Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 The Stream Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 The Byte Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 The Character Stream Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . 365 Binary Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 Console I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 Reading Console Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 Using ReadKey( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 Writing Console Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 FileStream and Byte-Oriented File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 Opening and Closing a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 Reading Bytes from a FileStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 Writing to a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 Using FileStream to Copy a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 Character-Based File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Using StreamWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Using a StreamReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 Redirecting the Standard Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 Reading and Writing Binary Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 BinaryWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 BinaryReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 Demonstrating Binary I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 13. C o n t e n t s xiii Random Access Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 Using MemoryStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Using StringReader and StringWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394 Converting Numeric Strings to Their Internal Representation . . . . . . . . . . . 396 15 Delegates, Events, and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . 399 Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 Delegate Method Group Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . 402 Using Instance Methods as Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . 402 Multicasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Covariance and Contravariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 System.Delegate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 Why Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 Anonymous Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 Anonymous Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 Pass Arguments to an Anonymous Method . . . . . . . . . . . . . . . . . . . . . 410 Return a Value from an Anonymous Method . . . . . . . . . . . . . . . . . . . 410 Use Outer Variables with Anonymous Methods . . . . . . . . . . . . . . . . . 412 Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 The Lambda Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 Expression Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 Statement Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419 A Multicast Event Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Instance Methods vs. Static Methods as Event Handlers . . . . . . . . . . 422 Using Event Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 Miscellaneous Event Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429 Use Anonymous Methods and Lambda Expressions with Events . . . . . . . . 429 .NET Event Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 Use EventHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432 Applying Events: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 16 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 437 Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437 Declaring a Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 Namespaces Prevent Name Conicts . . . . . . . . . . . . . . . . . . . . . . . . . . 440 using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 A Second Form of using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Namespaces Are Additive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444 Namespaces Can Be Nested . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446 The Global Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 Using the :: Namespace Alias Qualier . . . . . . . . . . . . . . . . . . . . . . . . 447 The Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451 #dene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457 Assemblies and the internal Access Modier . . . . . . . . . . . . . . . . . . . . . . . . . 457 The internal Access Modier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 17 Runtime Type ID, Reection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 459 Runtime Type Identication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 Testing a Type with is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 Using as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 Using typeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 Reection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 The Reection Core: System.Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 Using Reection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 Obtaining Information About Methods . . . . . . . . . . . . . . . . . . . . . . . . 465 Calling Methods Using Reection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 Obtaining a Types Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 Obtaining Types from Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475 Fully Automating Type Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483 Attribute Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483 Positional vs. Named Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Three Built-in Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 AttributeUsage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 The Conditional Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 The Obsolete Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 18 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 What Are Generics? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 A Simple Generics Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496 Generic Types Differ Based on Their Type Arguments . . . . . . . . . . . . 499 How Generics Improve Type Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 A Generic Class with Two Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 The General Form of a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 Constrained Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 Using a Base Class Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504 Using an Interface Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 Using the new( ) Constructor Constraint . . . . . . . . . . . . . . . . . . . . . . . 516 The Reference Type and Value Type Constraints . . . . . . . . . . . . . . . . 517 Using a Constraint to Establish a Relationship Between Two Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 Using Multiple Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521 Creating a Default Value of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . 522 Generic Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 Creating a Generic Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 15. C o n t e n t s xv Using Explicit Type Arguments to Call a Generic Method . . . . . . . . 527 Using a Constraint with a Generic Method . . . . . . . . . . . . . . . . . . . . . 527 Generic Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527 Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530 Comparing Instances of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534 Generic Class Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537 Using a Generic Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537 A Generic Derived Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 Overriding Virtual Methods in a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . 540 Overloading Methods That Use Type Parameters . . . . . . . . . . . . . . . . . . . . . 542 How Generic Types Are Instantiated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543 Some Generic Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 Final Thoughts on Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 19 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 What Is LINQ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 LINQ Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546 A Simple Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546 A Query Can Be Executed More Than Once . . . . . . . . . . . . . . . . . . . . 548 How the Data Types in a Query Relate . . . . . . . . . . . . . . . . . . . . . . . . . 549 The General Form of a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550 Filter Values with where . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551 Sort Results with orderby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552 A Closer Look at select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556 Use Nested from Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 Group Results with group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561 Use into to Create a Continuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563 Use let to Create a Variable in a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565 Join Two Sequences with join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566 Anonymous Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569 Create a Group Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 The Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574 The Basic Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574 Create Queries by Using the Query Methods . . . . . . . . . . . . . . . . . . . 575 Query Syntax vs. Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577 More Query-Related Extension Methods . . . . . . . . . . . . . . . . . . . . . . . 577 Deferred vs. Immediate Query Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580 Expression Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581 Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582 20 Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics . . . . . 585 Unsafe Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 Pointer Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586 Using unsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 Using xed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588 Accessing 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 e Pointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589 Pointer Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 Pointers and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 Pointers and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593 Multiple Indirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594 Arrays of Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 stackalloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596 Creating Fixed-Size Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596 Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 Nullable Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 Nullable Objects in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600 The ?? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601 Nullable Objects and the Relational and Logical Operators . . . . . . . 602 Partial Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 Partial Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604 Friend Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 Miscellaneous Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 readonly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606 const and volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607 The using Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607 extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608 Part II Exploring the C# Library 21 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615 The Members of System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615 The Math Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617 The .NET Structures Corresponding to the Built-in Value Types . . . . . . . . . 623 The Integer Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 The Floating-Point Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626 Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 Char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634 The Boolean Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640 The Array Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641 Sorting and Searching Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648 Reversing an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650 Copying an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651 Using a Predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 Using an Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653 BitConverter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 Generating Random Numbers with Random . . . . . . . . . . . . . . . . . . . . . . . . . 656 Memory Management and the GC Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657 Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659 The IComparable and IComparable Interfaces . . . . . . . . . . . . . . . . . . . . . 659 The IEquatable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660 17. C o n t e n t s xvii The IConvertible Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660 The ICloneable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660 IFormatProvider and IFormattable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662 22 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 Strings in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 The String Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664 The String Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664 The String Field, Indexer, and Property . . . . . . . . . . . . . . . . . . . . . . . . 665 The String Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665 The String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665 Padding and Trimming Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681 Inserting, Removing, and Replacing . . . . . . . . . . . . . . . . . . . . . . . . . . . 682 Changing Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683 Using the Substring( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684 The String Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684 Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684 Formatting Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685 The Numeric Format Speciers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686 Understanding Argument Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 687 Using String.Format( ) and ToString( ) to Format Data . . . . . . . . . . . . . . . . . 688 Using String.Format( ) to Format Values . . . . . . . . . . . . . . . . . . . . . . . 688 Using ToString( ) to Format Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 Creating a Custom Numeric Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692 The Custom Format Placeholder Characters . . . . . . . . . . . . . . . . . . . . 692 Formatting Date and Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695 Creating a Custom Date and Time Format . . . . . . . . . . . . . . . . . . . . . . 698 Formatting Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 23 Multithreaded Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 Multithreading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 The Thread Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704 Creating and Starting a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704 Some Simple Improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 Creating Multiple Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708 Determining When a Thread Ends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710 Passing an Argument to a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713 The IsBackground Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715 Thread Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717 An Alternative Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 The Monitor Class and lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723 Thread Communication Using Wait( ), Pulse( ), and PulseAll( ) . . . . . . . . . 723 An Example That Uses Wait( ) and Pulse( ) . . . . . . . . . . . . . . . . . . . . . 724 Deadlock and Race Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727 Using MethodImplAttribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728 Using 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 e The Mutex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 The Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734 Using Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737 The Interlocked Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739 Terminating a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741 An Abort( ) Alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742 Canceling Abort( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743 Suspending and Resuming a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 Determining a Threads State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 Using the Main Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 746 Multithreading Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747 Starting a Separate Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747 24 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749 Collections Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749 The Non-Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750 The Non-Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751 The DictionaryEntry Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 755 The Non-Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 755 Storing Bits with BitArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771 The Specialized Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774 The Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774 The Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775 The KeyValuePair Structure . . . . . . . . . . . . . . . . . . . . . . . . . 778 The Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779 Storing User-Dened Classes in Collections . . . . . . . . . . . . . . . . . . . . . . . . . . 799 Implementing IComparable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801 Implementing IComparable for Non-Generic Collections . . . . . . . . . 802 Implementing IComparable for Generic Collections . . . . . . . . . . 803 Using an IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805 Using a Non-Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805 Using a Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806 Accessing a Collection via an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808 Using an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808 Using the IDictionaryEnumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809 Implementing IEnumerable and IEnumerator . . . . . . . . . . . . . . . . . . . . . . . . 811 Using Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 813 Stopping an Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 815 Using Multiple yield Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 815 Creating a Named Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816 Creating a Generic Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 818 Collection Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 819 25 Networking Through the Internet Using System.Net . . . . . . . . . . . . . . . . . 821 The System.Net Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821 Uniform Resource Identiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 19. Internet Access Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 WebRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824 WebResponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826 HttpWebRequest and HttpWebResponse . . . . . . . . . . . . . . . . . . . . . . . 826 A Simple First Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827 Handling Network Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830 Exceptions Generated by Create( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830 Exceptions Generated by GetReponse( ) . . . . . . . . . . . . . . . . . . . . . . . . 830 Exceptions Generated by GetResponseStream( ) . . . . . . . . . . . . . . . . . 831 Using Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 831 The Uri Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833 Accessing Additional HTTP Response Information . . . . . . . . . . . . . . . . . . . . 834 Accessing the Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834 Accessing Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836 Using the LastModied Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838 MiniCrawler: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839 Using WebClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842 26 Use System.Windows.Forms to Create Form-Based Windows Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847 A Brief History of Windows Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . 847 Two Ways to Write a Form-Based Windows Application . . . . . . . . . . . . . . . 848 How Windows Interacts with the User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848 Windows Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849 The Form Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849 A Skeletal Form-Based Windows Program . . . . . . . . . . . . . . . . . . . . . . . . . . . 849 Compiling the Windows Skeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851 Adding a Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852 Button Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852 Adding a Button to a Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852 A Simple Button Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853 Handling Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853 An Alternative Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856 Using a Message Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856 Adding a Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 859 Creating a Traditional-Style Main Menu . . . . . . . . . . . . . . . . . . . . . . . 859 Creating a New-Style Menu with MenuStrip . . . . . . . . . . . . . . . . . . . 863 A Documentation Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . 867 The XML Comment Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867 Compiling Documentation Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 868 An XML Documentation Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 871 C o n t e n t s xix 20. This page intentionally left blank 21. Special Thanks S pecial thanks go to Michael Howard for his excellent technical edit of this book. His expertise, insights, suggestions, and advice were of great value. xxi 22. This page intentionally left blank 23. Preface W e programmers are a demanding bunch, always looking for ways to improve the performance, efficiency, and portability of our programs. We also demand much from the tools we use, especially when it comes to programming languages. There are many programming languages, but only a few are great. A great programming language must be powerful, yet flexible. Its syntax must be terse, but clear. It must facilitate the creation of correct code while not getting in our way. It must support state-of-the-art features, but not trendy dead ends. Finally, a great programming language must have one more, 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 programming heritage. Its chief architect was long-time programming guru Anders Hejlsberg. C# is directly descended from two of the worlds most successful computer languages: C and C++. From C, it derives its syntax, many of its keywords, and its operators. It builds upon and improves the object model defined by C++. C# is also closely related to another very successful language: Java. Sharing a common ancestry, but differing in many important ways, C# and Java are more like cousins. Both support distributed programming and both use intermediate code to achieve safety and portability, but the details differ. They both also provide a significant amount of runtime error checking, security, and managed execution, but again, the details differ. However, unlike Java, C# also gives you access to pointersa feature supported by C++. 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 to accommodate 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 its ability to respond rapidly to the changing needs of the programmer. This fact is testified to by 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 for programmers to write more resilient, reliable, and nimble code. Without question, the most important 2.0 addition was generics. Through the use of generics, it became possible to create type-safe, reusable code in C#. Thus, the addition of generics fundamentally expanded the power and scope of the language. Now consider the second major revision, C# 3.0. This is the latest version of C# and is the version described in this book. It is not an exaggeration to say that C# 3.0 has added features that have redefined the very core of C#, raising the bar in computer language development in the 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-style queries by using elements of the C# language. Lambda expressions implement a functional- style syntax that uses the => lambda operator, and lambda expressions are frequently used in LINQ expressions. As you will see in the course of this book, the combination of LINQ and lambda expressions represents a radically powerful subset of C#. Furthermore, they are revolutionary features that xxiii 24. xxiv C # 3 . 0 : T h e C o m p l e t e R e f e r e n c e are redefining how solutions are crafted for many different types of programming tasks, not just database queries. In essence, they let you approach old problems in new ways. Their use not only streamlines a solution, but also helps you conceptualize a problem from a different point of view. Simply put, the addition of LINQ and lambda expressions is both significant and far reaching. 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 programming landscape, C# has remained a vibrant and innovative language. As a result, it defines one of the most powerful, feature-rich languages in modern computing. It is also a language that no programmer can afford to ignore. This book is designed to help you master it. Whats Inside This book describes C# 3.0. It is divided into two parts. Part I provides a comprehensive discussion of the C# language, including the new features added by version 3.0. This is the largest part in the book, and it describes the keywords, syntax, and features that define the language. 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. This library is huge! Because of space limitations, it is not possible to cover the entire .NET Framework class library in one book. Instead, Part II focuses on the core library, which is contained 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 Programmers This book does not require any previous programming experience. If you already know C++ or Java, you will be able to advance quite rapidly because C# has much in common with those languages. If you dont have any previous programming experience, you will still be able to learn C# from this book, but you will need to work carefully through the examples in each chapter. Required Software To compile and run C# 3.0 programs, you must use Visual Studio 2008 or later. Dont Forget: Code on the Web Remember, the source code for all of the programs in this book is available free-of-charge on the Web at www.mhprofessional.com. 25. For Further Study C# 3.0: The Complete Reference is your gateway to the Herb Schildt series of programming books. Here are some others that you will find of interest. For a carefully paced introduction to C#, try C# 3.0: A Beginners Guide To learn about Java programming, we recommend the following: Java: The Complete Reference Java: A Beginners Guide Swing: A Beginners Guide The Art of Java Herb Schildts Java Programming Cookbook To learn about C++, you will find these books especially helpful: C++: The Complete Reference C++: A Beginners Guide C++ From the Ground Up STL Programming From the Ground Up The Art of C++ Herb Schildts C++ Programming Cookbook If you want to learn about the C language, the foundation of all modern programming, the following title will be of interest: C: The Complete Reference When 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. I The C# Language P art I discusses the elements of the C# language, including its keywords, syntax, and operators. Also described are several foundational C# techniques, such as using I/O and reflection, which are tightly linked with the C# language. CHAPTER 1 The Creation of C# CHAPTER 2 An Overview of C# CHAPTER 3 Data Types, Literals, and Variables CHAPTER 4 Operators CHAPTER 5 Program Control Statements CHAPTER 6 Introducing Classes and Objects CHAPTER 7 Arrays and Strings CHAPTER 8 A Closer Look at Methods and Classes CHAPTER 9 Operator Overloading CHAPTER 10 Indexers and Properties CHAPTER 11 Inheritance CHAPTER 12 Interfaces, Structures, and Enumerations CHAPTER 13 Exception Handling CHAPTER 14 Using I/O CHAPTER 15 Delegates, Events, and Lambda Expressions CHAPTER 16 Namespaces, the Preprocessor, and Assemblies CHAPTER 17 Runtime Type ID, Reection, and Attributes CHAPTER 18 Generics CHAPTER 19 LINQ CHAPTER 20 Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics PART 28. This page intentionally left blank 29. 1 The Creation of C# C # is Microsofts premier language for .NET development. It leverages time-tested features with cutting-edge innovations and provides a highly usable, efficient way to write programs for the modern enterprise computing environment. It is, by any measure, 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 forces that drove its creation, its design philosophy, and how it was influenced by other computer languages. This chapter also explains how C# relates to the .NET Framework. As you will see, C# and the .NET Framework work together to create a highly refined programming environment. C#s Family Tree Computer languages do not exist in a void. Rather, they relate to one another, with each new language influenced in one form or another by the ones that came before. In a process akin to cross-pollination, features from one language are adapted by another, a new innovation is integrated into an existing context, or an older construct is removed. In this way, languages evolve and the art of programming advances. C# is no exception. C# inherits a rich programming legacy. It is directly descended from two of the worlds most 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, we begin our examination of C# by placing it in the historical context of these three languages. C: The Beginning of the Modern Age of Programming The creation of C marks the beginning of the modern age of programming. C was invented by 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, C established the paradigm that still charts the course of programming today. C grew out of the structured programming revolution of the 1960s. Prior to structured programming, large programs were difficult to write because the program logic tended to degenerate into what is known as spaghetti code, a tangled mass of jumps, calls, and returns that is difficult to follow. Structured languages addressed this problem by adding well-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 CHAPTER 30. 4 P a r t I : T h e C # L a n g u a g e Although there were other structured languages at the time, C was the first to successfully combine power, elegance, and expressiveness. Its terse, yet easy-to-use syntax coupled with its philosophy that the programmer (not the language) was in charge quickly won many converts. It can be a bit hard to understand from todays perspective, but C was a breath of fresh air that programmers had long awaited. As a result, C became the most widely used structured programming language of the 1980s. However, even the venerable C language had its limits. One of the most troublesome was its inability to handle large programs. The C language hits a barrier once a project reaches a certain size, and after that point, C programs are difficult to understand and maintain. 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 becomes unmanageable. The Creation of OOP and C++ By the late 1970s, the size of many projects was near or at the limits of what structured programming methodologies and the C language could handle. To solve this problem, a new 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 was that 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 Murray Hill, New Jersey. He initially called the new language C with Classes. However, in 1983 the name was changed to C++. C++ contains the entire C language. Thus, C is the foundation upon which C++ is built. Most of the additions that Stroustrup made to C were designed to support object-oriented programming. In essence, C++ is the object-oriented version of C. By building 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 only a few new features before reaping the benefits of the object-oriented methodology. C++ simmered in the background during much of the 1980s, undergoing extensive development. By the beginning of the 1990s, C++ was ready for mainstream use, and its popularity exploded. By the end of the decade, it had become the most widely used programming language. Today, C++ is still the preeminent language for the development of high-performance system code. It is critical to understand that the invention of C++ was not an attempt to create an entirely new programming language. Instead, it was an enhancement to an already highly successful language. This approach to language developmentbeginning with an existing language and moving it forwardestablished a trend that continues today. The Internet and Java Emerge The next major advance in programming languages is Java. Work on Java, which was originally called Oak, began in 1991 at Sun Microsystems. The main driving force behind Javas design was James Gosling. Patrick Naughton, Chris Warth, Ed Frank, and Mike Sheridan also played a role. Java is a structured, object-oriented language with a syntax and philosophy derived from C++. The innovative aspects of Java were driven not so much by advances in the art of programming (although some certainly were), but rather by changes in the computing environment. Prior to the mainstreaming of the Internet, most programs were written, 31. PARTI C h a p t e r 1 : T h e C r e a t i o n o f C # 5 PARTIPARTI compiled, and targeted for a specific CPU and a specific operating system. While it has always been true that programmers like to reuse their code, the ability to port a program easily from one environment to another took a backseat to more pressing problems. However, with the rise of the Internet, in which many different types of CPUs and operating systems are connected, the old problem of portability reemerged with a vengeance. To solve the problem of 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 original impetus for Java was not the Internet, but rather the need for a platform-independent language that could be used to create software for embedded controllers. In 1993, it became clear that the issues of cross-platform portability found when creating code for embedded controllers 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 of computers live. The same techniques that solved the portability problem on a small scale could be applied to the Internet on a large scale. Java achieved portability by translating a programs source code into an intermediate language 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 was available. Also, since the JVM is relatively easy to implement, it was readily available for a large number of environments. Javas use of bytecode differed radically from both C and C++, which were nearly always compiled to executable machine code. Machine code is tied to a specific CPU and operating system. Thus, if you wanted to run a C/C++ program on a different system, it needed to be recompiled to machine code specifically for that environment. Therefore, to create a C/C++ program that would run in a variety of environments, several different executable versions of the program would be needed. Not only was this impractical, it was expensive. 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 object model is evolved from C++. Although Java code is neither upwardly nor downwardly compatible with C or C++, its syntax is sufficiently similar that the large pool of existing C/C++ programmers could move to Java with very little effort. Furthermore, because Java built upon and improved an existing paradigm, Gosling, et al., were free to focus their attention on the new and innovative features. Just as Stroustrup did not need to reinvent the wheel when creating C++, Gosling did not need to create an entirely new language when developing Java. Moreover, with the creation of Java, C and C++ became an accepted substrata upon which to base a new computer language. The Creation of C# While Java has successfully addressed many of the issues surrounding portability in the Internet 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 one language to work easily with the code produced by another. Cross-language interoperability is needed for the creation of large, distributed software systems. It is also desirable for programming software components because the most valuable component is one that can be used by the widest variety of computer languages, in the greatest number of operating environments. 32. 6 P a r t I : T h e C # L a n g u a g e Another feature lacking in Java is full integration with the Windows platform. Although Java programs can be executed in a Windows environment (assuming that the Java Virtual Machine has been installed), Java and Windows are not closely coupled. Since Windows is the most widely used operating system in the world, lack of direct support for Windows is a drawback to Java. To answer these and other needs, Microsoft developed C#. C# was created at Microsoft late in the 1990s and was part of Microsofts overall .NET strategy. It was first released in its alpha version in the middle of 2000. C#s chief architect was Anders Hejlsberg. Hejlsberg is one of the worlds leading language experts, with several notable accomplishments to his credit. For example, in the 1980s he was the original author of the highly successful and influential Turbo Pascal, whose streamlined implementation set the standard for all future compilers. C# is directly related to C, C++, and Java. This is not by accident. These are three of the 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 easy migration path from these languages. Since it was neither necessary nor desirable for Hejlsberg to 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 improves the 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 also descended 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 important ways. The good news, though, is that if you know Java, then many C# concepts will be familiar. Conversely, if in the future you need to learn Java, then many of the things you learn about C# will carry over. C# contains many innovative features that we will examine at length throughout the course of this book, but some of its most important relate to its built-in support for software components. In fact, C# has been characterized as being a component-oriented language because it contains integral support for the writing of software components. For example, FIGURE 1-1 The C# family tree 33. PARTI C h a p t e r 1 : T h e C r e a t i o n o f C # 7 PARTIPARTI C# includes fea