976

The c# 4.0 complete

Embed Size (px)

DESCRIPTION

All the basics and complete paracticle information related to C# language.

Citation preview

  • 1. C# 4.0: The Complete Reference

2. About the Author Herbert Schildt is a leading authority on C#, C++, C, and Java. His programming books have sold millions of 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, and C: The Complete Reference, among many others. 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 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 began his career with Microsoft in 1992 at the companys New Zealand office, working for the first two years with Windows and compilers on the Product Support Services team and then with Microsoft Consulting Services, where he provided security infrastructure support to customers and assisted in the design of custom solutions and development of software. In 1997, Howard moved to the United States to work for the Windows division on Internet Information Services, Microsofts next-generation web server, before moving to his current role in 2000. Howard is an editor of IEEE Security & Privacy, a frequent speaker at security-related conferences, and he regularly pub- lishes articles on secure coding and design. Howard is the co-author of six security books, including the award-winning Writing Secure Code, 24 Deadly Sins of Software Security, The Security Development Lifecycle, and his most recent release, Writing Secure Code for Windows Vista. 3. C# 4.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 2010 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-174117-0 MHID: 0-07-174117-8 The material in this eBook also appears in the print version of this title: ISBN: 978-0-07-174116-3, MHID: 0-07-174116-X. 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 benet 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 e-mail us at [email protected]. All trademarks or copyrights mentioned herein are the possession of their respective owners and McGraw-Hill makes no claim of ownership by the mention of products that contain these marks. 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. (McGrawHill) 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 DISCLAIM 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 6 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 7 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 8 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 9 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 10 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 11 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 12 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 13 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 14 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 15 Delegates, Events, and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . 411 16 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 449 17 Runtime Type ID, Reection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 471 18 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 19 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565 20 Unsafe Code, Pointers, Nullable Types, Dynamic Types, and Miscellaneous Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 Part II Exploring the C# Library 21 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 22 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 23 Multithreaded Programming, Part One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735 24 Multithreading, Part Two: Exploring the Task Parallel Library and PLINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783 25 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817 26 Networking Through the Internet Using System.Net . . . . . . . . . . . . . . . . . 895 A Documentation Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . 921 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 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 . . . . . . . . . . . . . . . . . . . . . . . . 21 Handling Syntax Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 A Small Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 A Second Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Another Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Two Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Using Code Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Semicolons, Positioning, and Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 The C# Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Identiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 The .NET Framework Class Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 vii 8. viii C # 4 . 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Why Data Types Are Important . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 C#s Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 Floating-Point Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 The decimal Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 The bool Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Some Output Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Hexadecimal Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Character Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 A Closer Look at Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Initializing a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Dynamic Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Implicitly Typed Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 The Scope and Lifetime of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Type Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Automatic Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Casting Incompatible Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Type Conversion in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Using Casts in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 4 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Increment and Decrement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Relational and Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Short-Circuit Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 The Assignment Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 The Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 The Bitwise AND, OR, XOR, and NOT Operators . . . . . . . . . . . . . . . 75 The Shift Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Bitwise Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 The ? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Spacing and Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 5 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Nested ifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 The if-else-if Ladder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 Nested switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 9. C o n t e n t s ix The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Some Variations on the for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 The while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 The do-while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Using break to Exit a Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Using continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 The goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Class Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 The General Form of a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Dene a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 How Objects Are Created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 Reference Variables and Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Add a Method to the Building Class . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Return from a Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Return a Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Use Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Add a Parameterized Method to Building . . . . . . . . . . . . . . . . . . . . . . 127 Avoiding Unreachable Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Parameterized Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Add a Constructor to the Building Class . . . . . . . . . . . . . . . . . . . . . . . 131 The new Operator Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Using new with Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Garbage Collection and Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 The this Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 7 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 One-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Two-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Arrays of Three or More Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Initializing Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Assigning Array References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Using the Length Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Using Length with Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Implicitly Typed Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 10. x C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Constructing Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Operating on Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Arrays of Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Strings Are Immutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Strings Can Be Used in switch Statements . . . . . . . . . . . . . . . . . . . . . . 166 8 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Controlling Access to Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 C#s Access Modiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Applying Public and Private Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Controlling Access: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Pass References to Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 How Arguments Are Passed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Use ref and out Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Use ref . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Use out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Use ref and out on References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 Use a Variable Number of Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Return Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Return an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Method Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Overload Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Invoke an Overloaded Constructor Through this . . . . . . . . . . . . . . . . 199 Object Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Optional Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Optional Arguments vs. Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . 204 Optional Arguments and Ambiguity . . . . . . . . . . . . . . . . . . . . . . . . . . 204 A Practical Example of Optional Arguments . . . . . . . . . . . . . . . . . . . . 205 Named Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 The Main( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Return Values from Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Pass Arguments to Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 Understanding static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Static Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Static Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 9 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Operator Overloading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Overloading Binary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Overloading Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Handling Operations on C# Built-in Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 Overloading the Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 Overloading true and false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 11. C o n t e n t s xi Overloading the Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 A Simple Approach to Overloading the Logical Operators . . . . . . . . 237 Enabling the Short-Circuit Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Conversion Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Operator Overloading Tips and Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Another Example of Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 10 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Creating One-Dimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Indexers Can Be Overloaded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 Indexers Do Not Require an Underlying Array . . . . . . . . . . . . . . . . . . 259 Multidimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Auto-Implemented Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 Use Object Initializers with Properties . . . . . . . . . . . . . . . . . . . . . . . . . 268 Property Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Use Access Modiers with Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Using Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 11 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Inheritance Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Member Access and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Using Protected Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Constructors and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 Calling Base Class Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 Inheritance and Name Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 Using base to Access a Hidden Name . . . . . . . . . . . . . . . . . . . . . . . . . . 291 Creating a Multilevel Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 When Are Constructors Called? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Base Class References and Derived Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Virtual Methods and Overriding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Why Overridden Methods? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 Applying Virtual Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 Using Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 Using sealed to Prevent Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 The object Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 Boxing and Unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Is object a Universal Data Type? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 12 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Implementing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 Using Interface References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 Interface Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Interface Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 12. xii C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e Interfaces Can Be Inherited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 Name Hiding with Interface Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Explicit Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Choosing Between an Interface and an Abstract Class . . . . . . . . . . . . . . . . . . 334 The .NET Standard Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 Why Structures? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340 Initialize an Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 Specify the Underlying Type of an Enumeration . . . . . . . . . . . . . . . . 342 Use Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 13 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 The System.Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 Exception-Handling Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Using try and catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 A Simple Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 A Second Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 The Consequences of an Uncaught Exception . . . . . . . . . . . . . . . . . . . . . . . . . 349 Exceptions Let You Handle Errors Gracefully . . . . . . . . . . . . . . . . . . . . . . . . . 351 Using Multiple catch Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Catching All Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 Nesting try Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Throwing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 Rethrowing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Using nally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 A Closer Look at the Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Commonly Used Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 Deriving Exception Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 Catching Derived Class Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Using checked and unchecked . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368 14 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 C#s I/O Is Built Upon Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 Byte Streams and Character Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 The Predened Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 The Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 The Stream Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 The Byte Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 The Character Stream Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . 374 Binary Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 Console I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 Reading Console Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 Using ReadKey( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 Writing Console Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 13. C o n t e n t s xiii FileStream and Byte-Oriented File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 Opening and Closing a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 Reading Bytes from a FileStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382 Writing to a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 Using FileStream to Copy a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 Character-Based File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 Using StreamWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 Using a StreamReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 Redirecting the Standard Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 Reading and Writing Binary Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 BinaryWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 BinaryReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Demonstrating Binary I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394 Random Access Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398 Using MemoryStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 Using StringReader and StringWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 The File Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Using Copy( ) to Copy a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Using Exists( ) and GetLastAccessTime( ) . . . . . . . . . . . . . . . . . . . . . . 405 Converting Numeric Strings to Their Internal Representation . . . . . . . . . . . 406 15 Delegates, Events, and Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . 411 Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 Delegate Method Group Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . 414 Using Instance Methods as Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . 414 Multicasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 Covariance and Contravariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418 System.Delegate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Why Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Anonymous Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 Anonymous Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Pass Arguments to an Anonymous Method . . . . . . . . . . . . . . . . . . . . . 422 Return a Value from an Anonymous Method . . . . . . . . . . . . . . . . . . . 422 Use Outer Variables with Anonymous Methods . . . . . . . . . . . . . . . . . 424 Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 The Lambda Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Expression Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 Statement Lambdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431 A Multicast Event Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 Instance Methods vs. Static Methods as Event Handlers . . . . . . . . . . 434 Using Event Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436 Miscellaneous Event Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Use Anonymous Methods and Lambda Expressions with Events . . . . . . . . 441 14. xiv C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e .NET Event Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442 Use EventHandler and EventHandler . . . . . . . . . . . . 444 Applying Events: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 16 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 449 Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 Declaring a Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 Namespaces Prevent Name Conicts . . . . . . . . . . . . . . . . . . . . . . . . . . 452 using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 A Second Form of using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455 Namespaces Are Additive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 Namespaces Can Be Nested . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 The Global Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 Using the :: Namespace Alias Qualier . . . . . . . . . . . . . . . . . . . . . . . . 459 The Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 #dene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 #if and #endif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 #else and #elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 #undef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 #error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 #warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 #line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 #region and #endregion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 #pragma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 Assemblies and the internal Access Modier . . . . . . . . . . . . . . . . . . . . . . . . . 469 The internal Access Modier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 17 Runtime Type ID, Reection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 471 Runtime Type Identication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 Testing a Type with is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 Using as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 Using typeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 Reection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475 The Reection Core: System.Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475 Using Reection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 Obtaining Information About Methods . . . . . . . . . . . . . . . . . . . . . . . . 477 Calling Methods Using Reection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 Obtaining a Types Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483 Obtaining Types from Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 Fully Automating Type Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 Attribute Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 Positional vs. Named Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 Three Built-in Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 AttributeUsage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 The Conditional Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 The Obsolete Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 15. C o n t e n t s xv 18 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 What Are Generics? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 A Simple Generics Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508 Generic Types Differ Based on Their Type Arguments . . . . . . . . . . . . 511 How Generics Improve Type Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . 511 A Generic Class with Two Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 The General Form of a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515 Constrained Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515 Using a Base Class Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 Using an Interface Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524 Using the new( ) Constructor Constraint . . . . . . . . . . . . . . . . . . . . . . . 528 The Reference Type and Value Type Constraints . . . . . . . . . . . . . . . . 529 Using a Constraint to Establish a Relationship Between Two Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532 Using Multiple Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533 Creating a Default Value of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . 534 Generic Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535 Creating a Generic Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536 Using Explicit Type Arguments to Call a Generic Method . . . . . . . . 539 Using a Constraint with a Generic Method . . . . . . . . . . . . . . . . . . . . . 539 Generic Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541 Comparing Instances of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 Generic Class Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548 Using a Generic Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549 A Generic Derived Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551 Overriding Virtual Methods in a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . 552 Overloading Methods That Use Type Parameters . . . . . . . . . . . . . . . . . . . . . 553 Covariance and Contravariance in Generic Type Parameters . . . . . . . . . . . . 555 Using Covariance in a Generic Interface . . . . . . . . . . . . . . . . . . . . . . . . 555 Using Contravariance in a Generic Interface . . . . . . . . . . . . . . . . . . . . 558 Variant Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561 How Generic Types Are Instantiated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563 Some Generic Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564 Final Thoughts on Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564 19 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565 LINQ Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566 A Simple Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566 A Query Can Be Executed More Than Once . . . . . . . . . . . . . . . . . . . . 568 How the Data Types in a Query Relate . . . . . . . . . . . . . . . . . . . . . . . . . 569 The General Form of a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570 Filter Values with where . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 Sort Results with orderby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572 A Closer Look at select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576 Use Nested from Clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580 16. xvi C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e Group Results with group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581 Use into to Create a Continuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 Use let to Create a Variable in a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 Join Two Sequences with join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586 Anonymous Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589 Create a Group Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 The Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594 The Basic Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594 Create Queries by Using the Query Methods . . . . . . . . . . . . . . . . . . . 595 Query Syntax vs. Query Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 More Query-Related Extension Methods . . . . . . . . . . . . . . . . . . . . . . . 597 Deferred vs. Immediate Query Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600 Expression Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601 Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602 PLINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604 20 Unsafe Code, Pointers, Nullable Types, Dynamic Types, and Miscellaneous Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 Unsafe Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 Pointer Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606 Using unsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607 Using xed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608 Accessing Structure Members Through a Pointer . . . . . . . . . . . . . . . . 609 Pointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609 Pointer Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611 Pointers and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611 Pointers and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613 Multiple Indirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 614 Arrays of Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615 stackalloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616 Creating Fixed-Size Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616 Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618 Nullable Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618 Nullable Objects in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620 The ?? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621 Nullable Objects and the Relational and Logical Operators . . . . . . . 622 Partial Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 Partial Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624 Create a Dynamic Type with dynamic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625 COM Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629 Friend Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 Miscellaneous Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 readonly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631 17. C o n t e n t s xvii const and volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632 The using Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632 extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633 Part II Exploring the C# Library 21 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 The Members of System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 The Math Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641 The .NET Structures Corresponding to the Built-in Value Types . . . . . . . . . 646 The Integer Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647 The Floating-Point Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649 Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 Char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657 The Boolean Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662 The Array Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 Sorting and Searching Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672 Reversing an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675 Copying an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676 Using a Predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677 Using an Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 678 BitConverter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680 Generating Random Numbers with Random . . . . . . . . . . . . . . . . . . . . . . . . . 681 Memory Management and the GC Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682 Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684 Tuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685 The IComparable and IComparable Interfaces . . . . . . . . . . . . . . . . . . . . . 685 The IEquatable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686 The IConvertible Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686 The ICloneable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686 IFormatProvider and IFormattable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688 IObservable and IObserver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689 22 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 Strings in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 The String Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692 The String Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692 The String Field, Indexer, and Property . . . . . . . . . . . . . . . . . . . . . . . . 693 The String Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 The String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 Padding and Trimming Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711 Inserting, Removing, and Replacing . . . . . . . . . . . . . . . . . . . . . . . . . . . 713 Changing Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714 Using the Substring( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714 The String Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715 18. xviii C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715 Formatting Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715 The Numeric Format Speciers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716 Understanding Argument Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 718 Using String.Format( ) and ToString( ) to Format Data . . . . . . . . . . . . . . . . . 719 Using String.Format( ) to Format Values . . . . . . . . . . . . . . . . . . . . . . . 719 Using ToString( ) to Format Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 Creating a Custom Numeric Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 722 The Custom Format Placeholder Characters . . . . . . . . . . . . . . . . . . . . 722 Formatting Date and Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 726 Creating a Custom Date and Time Format . . . . . . . . . . . . . . . . . . . . . . 728 Formatting Time Spans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 Formatting Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732 23 Multithreaded Programming, Part One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735 Multithreading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736 The Thread Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737 Creating and Starting a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737 Some Simple Improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739 Creating Multiple Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 740 Determining When a Thread Ends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742 Passing an Argument to a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 The IsBackground Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747 Thread Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750 An Alternative Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754 The Monitor Class and lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 755 Thread Communication Using Wait( ), Pulse( ), and PulseAll( ) . . . . . . . . . 756 An Example That Uses Wait( ) and Pulse( ) . . . . . . . . . . . . . . . . . . . . . 756 Deadlock and Race Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 760 Using MethodImplAttribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 760 Using a Mutex and a Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762 The Mutex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762 The Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766 Using Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 769 The Interlocked Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772 Synchronization Classes Added by .NET 4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . 773 Terminating a Thread Via Abort( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774 An Abort( ) Alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775 Canceling Abort( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777 Suspending and Resuming a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778 Determining a Threads State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779 Using the Main Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779 Additional Multithreading Features Added by .NET 4.0 . . . . . . . . . . . . . . . . 780 Multithreading Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781 Starting a Separate Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781 19. 24 Multithreading, Part Two: Exploring the Task Parallel Library and PLINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783 Two Approaches to Parallel Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784 The Task Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784 Creating a Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784 Use a Task ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787 Using Wait Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789 Calling Dispose( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791 Using TaskFactory to Start a Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792 Use a Lambda Expression as a Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792 Create a Task Continuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794 Returning a Value from a Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796 Cancelling a Task and Using AggregateException . . . . . . . . . . . . . . . . . . . . . 798 Some Other Task Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801 The Parallel Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801 Parallelizing Tasks via Invoke( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 802 Using the For( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 804 Using the ForEach( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810 Exploring PLINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812 ParallelEnumerable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812 Parallelizing a Query with AsParallel( ) . . . . . . . . . . . . . . . . . . . . . . . . 812 Using AsOrdered( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814 Cancelling a Parallel Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814 Other PLINQ Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816 PLINQ Efciency Concerns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816 25 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817 Collections Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817 The Non-Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 818 The Non-Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 819 The DictionaryEntry Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 The Non-Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 824 Storing Bits with BitArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 840 The Specialized Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843 The Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843 The Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 844 The KeyValuePair Structure . . . . . . . . . . . . . . . . . . . . 848 The Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848 The Concurrent Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869 Storing User-Dened Classes in Collections . . . . . . . . . . . . . . . . . . . . . . . . . . 873 Implementing IComparable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875 Implementing IComparable for Non-Generic Collections . . . . . . . . . 875 Implementing IComparable for Generic Collections . . . . . . . . . . 877 Using an IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 878 Using a Non-Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 879 Using a Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 880 C o n t e n t s xix 20. xx C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e Using StringComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 881 Accessing a Collection via an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882 Using an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 883 Using IDictionaryEnumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884 Implementing IEnumerable and IEnumerator . . . . . . . . . . . . . . . . . . . . . . . . 885 Using Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 887 Stopping an Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 889 Using Multiple yield Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 890 Creating a Named Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 890 Creating a Generic Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892 Collection Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893 26 Networking Through the Internet Using System.Net . . . . . . . . . . . . . . . . . 895 The System.Net Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 895 Uniform Resource Identiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897 Internet Access Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 898 WebRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899 WebResponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900 HttpWebRequest and HttpWebResponse . . . . . . . . . . . . . . . . . . . . . . . 901 A Simple First Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901 Handling Network Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904 Exceptions Generated by Create( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904 Exceptions Generated by GetReponse( ) . . . . . . . . . . . . . . . . . . . . . . . . 905 Exceptions Generated by GetResponseStream( ) . . . . . . . . . . . . . . . . . 905 Using Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905 The URI Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 907 Accessing Additional HTTP Response Information . . . . . . . . . . . . . . . . . . . . 908 Accessing the Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908 Accessing Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 910 Using the LastModied Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912 MiniCrawler: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913 Using WebClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 916 A Documentation Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . 921 The XML Comment Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921 Compiling Documentation Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 922 An XML Documentation Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 923 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925 21. Special Thanks S pecial thanks go to Michael Howard for his excellent technical edit of this book. His 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, yet 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 most of 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 following. The first major revision of C# was version 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. The second major revision was version 3.0. It is not an exaggeration to say that 3.0 added features that 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. xxiii 24. xxiv C # 4 . 0 : T h e C o m p l e t e R e f e r e n c e The third major revision is C# 4.0, and this is the version described in this book. It builds upon the previous releases by providing a number of new features that streamline common programming tasks. For example, it adds named and optional arguments. These make some types of method calls more convenient. It adds the dynamic keyword, which facilitates the use of C# in situations in which a data type is obtained at runtime, such as when interfacing to COM or when using reflection. The covariance and contravariance features already supported by C# have been expanded for use with type parameters. Through enhancements to the .NET Framework (which is C#s library), support for parallel programming is provided by the Task Parallel Library (TPL) and by Parallel LINQ (PLINQ). These subsystems make it easy to create code that automatically scales to better utilize multicore computers. Thus, with the release of 4.0, C# is ready to take advantage of high-performance computing platforms. 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# 4.0. It is divided into two parts. Part I provides a comprehensive discussion of the C# language, including the new features added by version 4.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, the Task Parallel Library and PLINQ, and networking. 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 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# 4.0 programs, you must use Visual Studio 2010 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# 4.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. 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 more 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 1 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, Dynamic 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 twenty-first 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, it was C that 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 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 environment. Prior to the mainstreaming of the Internet, most programs were written, 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