c# 2.0 : the complete reference - nyíregyházi...

914

Upload: others

Post on 20-Apr-2020

15 views

Category:

Documents


0 download

TRANSCRIPT

  • C# 2.0: The Complete Reference,

    Second Edition

    http://dx.doi.org/10.1036/0072262095

  • About the AuthorHerbert Schildt is the world’s leading programming author. He is an authority on the C, C++, Java, and C# languages, and is a master Windows programmer. 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 Beginner’s Guide. 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.

    Copyright © 2006 by The McGraw-Hill Companies. Click here for terms of use.

    www.HerbSchildt.com

  • C# 2.0: The Complete Reference,

    Second EditionHerbert Schildt

    McGraw-Hill/OsborneNew York Chicago San Francisco

    Lisbon London Madrid Mexico City Milan New Delhi San Juan

    Seoul Singapore Sydney Toronto

    http://dx.doi.org/10.1036/0072262095

  • Copyright © 2006 by The McGraw-Hill Companies. All rights reserved. Manufactured in the United States of America. Except as permit-ted under the United States Copyright Act of 1976, no part of this publication may be reproduced or distributed in any form or by anymeans, or stored in a database or retrieval system, without the prior written permission of the publisher.

    0-07-148373-X

    The material in this eBook also appears in the print version of this title: 0-07-226209-5.

    All trademarks are trademarks of their respective owners. Rather than put a trademark symbol after every occurrence of a trademarkedname, we use names in an editorial fashion only, and to the benefit of the trademark owner, with no intention of infringement of the trade-mark. 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 trainingprograms. For more information, please contact George Hoare, Special Sales, at [email protected] or (212) 904-4069.

    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 copyof the work, you may not decompile, disassemble, reverse engineer, reproduce, modify, create derivative works based upon, transmit, dis-tribute, disseminate, sell, publish or sublicense the work or any part of it without McGraw-Hill’s prior consent. You may use the work foryour own noncommercial and personal use; any other use of the work is strictly prohibited. Your right to use the work may be terminatedif you fail to comply with these terms.

    THE WORK IS PROVIDED “AS IS.” McGRAW-HILL AND ITS LICENSORS MAKE NO GUARANTEES OR WARRANTIES AS TOTHE ACCURACY, ADEQUACY OR COMPLETENESS OF OR RESULTS TO BE OBTAINED FROM USING THE WORK, INCLUD-ING ANY INFORMATION THAT CAN BE ACCESSED THROUGH THE WORK VIA HYPERLINK OR OTHERWISE, ANDEXPRESSLY DISCLAIM ANY WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WAR-RANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. McGraw-Hill and its licensors do not warrant orguarantee 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, inthe work or for any damages resulting therefrom. McGraw-Hill has no responsibility for the content of any information accessed throughthe work. Under no circumstances shall McGraw-Hill and/or its licensors be liable for any indirect, incidental, special, punitive, conse-quential 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 possibili-ty 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.

    DOI: 10.1036/0072262095

    http://dx.doi.org/10.1036/0072262095

  • We hope you enjoy thisMcGraw-Hill eBook! If

    you’d like more information about this book,its author, or related books and websites,please click here.

    Professional

    Want to learn more?

    http://dx.doi.org/10.1036/0072262095

  • Contents

    Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix

    Part I The C# Language

    1 The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3C#’s Family Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

    C: The Beginning of the Modern Age of Programming . . . . . . . . . . . 3The Creation of OOP and C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4The Internet and Java Emerge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4The Creation of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5The Evolution of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

    How C# Relates to the .NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7What Is the .NET Framework? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    How the Common Language Runtime Works . . . . . . . . . . . . . . . . . . . . . . . . . 8Managed vs. Unmanaged Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    The Common Language Specifi cation . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    2 An Overview of C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Object-Oriented Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    A First Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13Using csc.exe, the C# Command-Line Compiler . . . . . . . . . . . . . . . . . 14Using the Visual Studio IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15The First Sample Program, Line by Line . . . . . . . . . . . . . . . . . . . . . . . . 18

    Handling Syntax Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21A Small Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22A Second Simple Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22Another Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    v

    For more information about this title, click here

    http://dx.doi.org/10.1036/0072262095

  • vi C # : T h e C o m p l e t e R e f e r e n c e

    Two Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

    Using Blocks of Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29Semicolons, Positioning, and Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31The C# Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32Identifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33The C# Class Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

    3 Data Types, Literals, and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Why Data Types Are Important . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35C#’s Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36Floating-Point Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38The decimal Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42The bool Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42Some Output Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

    Hexadecimal Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47Character Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

    A Closer Look at Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50Initializing a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50Dynamic Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

    The Scope and Lifetime of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52Type Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

    Automatic Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55Casting Incompatible Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

    Type Conversion in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58Using Casts in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

    4 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    Increment and Decrement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64Relational and Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

    Short-Circuit Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70The Assignment Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

    Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72The Bitwise Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

    The Bitwise AND, OR, XOR, and NOT Operators . . . . . . . . . . . . . . . 73The Shift Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79Bitwise Compound Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

    The ? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82Spacing and Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

  • C o n t e n t s vii

    5 Program Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85The if Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

    Nested ifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86The if-else-if Ladder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

    The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88Nested switch Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

    The for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92Some Variations on the for Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

    The while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100The do-while Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102Using break to Exit a Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103Using continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

    return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106The goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

    6 Introducing Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109Class Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

    The General Form of a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109Defi ning a Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

    How Objects Are Created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114Reference Variables and Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

    Adding a Method to the Building Class . . . . . . . . . . . . . . . . . . . . . . . . 117Returning from a Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119Returning a Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120Using Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122Adding a Parameterized Method to Building . . . . . . . . . . . . . . . . . . . 124Avoiding Unreachable Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

    Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126Parameterized Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127Adding a Constructor to the Building Class . . . . . . . . . . . . . . . . . . . . 128

    The new Operator Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129Using new with Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

    Garbage Collection and Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

    The this Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

    7 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

    One-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

    Two-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139Arrays of Three or More Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . 140Initializing Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 142

    Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

  • viii C # : T h e C o m p l e t e R e f e r e n c e

    Assigning Array References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145Using the Length Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

    Using Length with Jagged Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148The foreach Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

    Constructing Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153Operating on Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154Arrays of Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157Strings Are Immutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158Strings Can Be Used in switch Statements . . . . . . . . . . . . . . . . . . . . . . 159

    8 A Closer Look at Methods and Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161Controlling Access to Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

    C#’s Access Modifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161Applying Public and Private Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 163Controlling Access: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

    Pass References to Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169How Arguments Are Passed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

    Using ref and out Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172Using ref . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173Using out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174Using ref and out on References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

    Using a Variable Number of Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178Returning Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

    Returning an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183Method Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185Overloading Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

    Invoking an Overloaded Constructor Through this . . . . . . . . . . . . . . 194The Main( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

    Returning Values from Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195Passing Arguments to Main( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

    Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197Understanding static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

    Static Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205Static Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

    9 Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209Operator Overloading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209

    Overloading Binary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210Overloading Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

    Handling Operations on C# Built-In Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 216Overloading the Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220Overloading true and false . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222Overloading the Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

    A Simple Approach to Overloading the Logical Operators . . . . . . . . 225Enabling the Short-Circuit Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 227

  • C o n t e n t s ix

    Conversion Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231Operator Overloading Tips and Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . 235Another Example of Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

    10 Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

    Creating One-Dimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . 241Indexers Can Be Overloaded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245Indexers Do Not Require an Underlying Array . . . . . . . . . . . . . . . . . . 247Multidimensional Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248

    Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250Property Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

    Using Access Modifi ers with Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256Using Indexers and Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

    11 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263Inheritance Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263Member Access and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266

    Using Protected Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269Constructors and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270

    Calling Base Class Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272Inheritance and Name Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

    Using base to Access a Hidden Name . . . . . . . . . . . . . . . . . . . . . . . . . . 277Creating a Multilevel Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279When Are Constructors Called? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282Base Class References and Derived Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 283Virtual Methods and Overriding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

    Why Overridden Methods? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291Applying Virtual Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291

    Using Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294Using sealed to Prevent Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298The object Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299

    Boxing and Unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300Is object a Universal Data Type? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302

    12 Interfaces, Structures, and Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

    Implementing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306Using Interface References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310Interface Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312Interface Indexers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314Interfaces Can Be Inherited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316Name Hiding with Interface Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317Explicit Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317

    Creating a Private Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318Using Explicit Implementation to Remove Ambiguity . . . . . . . . . . . 319

  • x C # : T h e C o m p l e t e R e f e r e n c e

    Choosing Between an Interface and an Abstract Class . . . . . . . . . . . . . . . . . . 320The .NET Standard Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320An Interface Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325

    Why Structures? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330

    Initialize an Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332Specifying the Base Type of an Enumeration . . . . . . . . . . . . . . . . . . . . 333Using Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

    13 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335The System.Exception Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335Exception Handling Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336

    Using try and catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336A Simple Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337A Second Exception Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338

    The Consequences of an Uncaught Exception . . . . . . . . . . . . . . . . . . . . . . . . . 339Exceptions Let You Handle Errors Gracefully . . . . . . . . . . . . . . . . . . . . . . . . . 341Using Multiple catch Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342Catching All Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343Nesting try Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344Throwing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345

    Rethrowing an Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346Using fi nally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347A Closer Look at Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348

    Commonly Used Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350Deriving Exception Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352Catching Derived Class Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355Using checked and unchecked . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357

    14 Using I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361C#’s I/O Is Built Upon Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361

    Byte Streams and Character Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . 361The Predefi ned Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361

    The Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362The Stream Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362The Byte Stream Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363The Character Stream Wrapper Classes . . . . . . . . . . . . . . . . . . . . . . . . 364Binary Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365

    Console I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365Reading Console Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365Using ReadKey( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367Writing Console Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369

    FileStream and Byte-Oriented File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370Opening and Closing a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370Reading Bytes from a FileStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372

  • C o n t e n t s xi

    Writing to a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373Using FileStream to Copy a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374

    Character-Based File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375Using StreamWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376Using a StreamReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378

    Redirecting the Standard Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379Reading and Writing Binary Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380

    BinaryWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380BinaryReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381Demonstrating Binary I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

    Random Access Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387Using MemoryStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389Using StringReader and StringWriter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390Converting Numeric Strings to Their Internal Representation . . . . . . . . . . . 392

    15 Delegates and Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395

    Delegate Method Group Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . 398Using Instance Methods as Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . 398Multicasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400Anonymous Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402Covariance and Contravariance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406System.Delegate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408Why Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408

    Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409A Multicast Event Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411Instance Methods vs. static Methods as Event Handlers . . . . . . . . . . 412Using Event Accessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414Miscellaneous Event Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418

    .NET Event Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419Using EventHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421

    Using Anonymous Methods with Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421Applying Events: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423

    16 Namespaces, the Preprocessor, and Assemblies . . . . . . . . . . . . . . . . . . . . . . 425Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425

    Declaring a Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429A Second Form of using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431Namespaces Are Additive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432Namespaces Can Be Nested . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434The Default Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435Using the :: Namespace Alias Qualifi er . . . . . . . . . . . . . . . . . . . . . . . . 435

    The Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439#defi ne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440#if and #endif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440

  • xii C # : T h e C o m p l e t e R e f e r e n c e

    #else and #elif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442#undef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443#error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444#warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444#line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444#region and #endregion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444#pragma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445

    Assemblies and the internal Access Modifi er . . . . . . . . . . . . . . . . . . . . . . . . . 445The internal Access Modifi er . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446

    17 Runtime Type ID, Refl ection, and Attributes . . . . . . . . . . . . . . . . . . . . . . . . 447Runtime Type Identifi cation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447

    Testing a Type with is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447Using as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448Using typeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450

    Refl ection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451The Refl ection Core: System.Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451

    Using Refl ection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453Obtaining Information About Methods . . . . . . . . . . . . . . . . . . . . . . . . 453Calling Methods Using Refl ection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457Obtaining a Type’s Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459Obtaining Types from Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463Fully Automating Type Discovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469

    Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471Attribute Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471Positional vs. Named Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

    Three Built-in Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478AttributeUsage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479The Conditional Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479The Obsolete Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480

    18 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483What Are Generics? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483A Simple Generics Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484

    Generic Types Differ Based on Their Type Arguments . . . . . . . . . . . . 487How Generics Improve Type Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . 487

    A Generic Class with Two Type Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 489The General Form of a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491Constrained Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491

    Using a Base Class Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492Using an Interface Constraint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500Using the new( ) Constructor Constraint . . . . . . . . . . . . . . . . . . . . . . . 504The Reference Type and Value Type Constraints . . . . . . . . . . . . . . . . 505Using a Constraint to Establish a Relationship Between Two Type

    Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507Using Multiple Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508

  • C o n t e n t s xiii

    Creating a Default Object of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . 509Generic Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511Creating a Generic Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512

    Using Explicit Type Arguments to Call a Generic Method . . . . . . . . 515Using a Constraint with a Generic Method . . . . . . . . . . . . . . . . . . . . . 515

    Generic Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519Comparing Instances of a Type Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522Generic Class Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526

    Using a Generic Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526A Generic Derived Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528

    Overriding Virtual Methods in a Generic Class . . . . . . . . . . . . . . . . . . . . . . . . 529Overloading Methods That Use Type Parameters . . . . . . . . . . . . . . . . . . . . . 530How Generic Types Are Instantiated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532Some Generic Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532Final Thoughts on Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532

    19 Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics . . . . . 533Unsafe Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533

    Pointer Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534Using unsafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536Using fi xed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536Accessing Structure Members Through a Pointer . . . . . . . . . . . . . . . . 537Pointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538Pointer Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539Pointers and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540Pointers and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542Multiple Indirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543Arrays of Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544sizeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544stackalloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544Creating Fixed-Size Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545

    Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546Nullable Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547Nullable Objects in Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548The ?? Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549Nullable Objects and the Relational and Logical Operators . . . . . . . 550

    Partial Class Defi nitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551Friend Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552Miscellaneous Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553

    lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553readonly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553The using Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554const and volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555

  • xiv C # : T h e C o m p l e t e R e f e r e n c e

    Part II Exploring the C# Library 20 Exploring the System Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561

    The Members of System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561The Math Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564The .NET Structures Corresponding to the Built-in Value Types . . . . . . . . . 569

    The Integer Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570The Floating-Point Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577Char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583The Boolean Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588

    The Array Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590Sorting and Searching Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590Reversing an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592Copying an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593Using a Predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594Using an Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596

    BitConverter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 610Generating Random Numbers with Random . . . . . . . . . . . . . . . . . . . . . . . . . 612Memory Management and the GC Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615The IComparable and IComparable Interfaces . . . . . . . . . . . . . . . . . . . . . 615The IConvertible Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616The ICloneable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616IFormatProvider and IFormattable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618The IEquatable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618

    21 Strings and Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619Strings in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619The String Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620

    The String Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620The String Field, Indexer, and Property . . . . . . . . . . . . . . . . . . . . . . . . 621The String Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621The String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621Padding and Trimming Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638Inserting, Removing, and Replacing . . . . . . . . . . . . . . . . . . . . . . . . . . . 640Changing Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641Using the Substring( ) Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641

    Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642Formatting Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642The Numeric Format Specifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643Understanding Argument Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . 645

    Using String.Format( ) and ToString( ) to Format Data . . . . . . . . . . . . . . . . . 646Using String.Format( ) to Format Values . . . . . . . . . . . . . . . . . . . . . . . 646Using ToString( ) to Format Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648

  • C o n t e n t s xv

    Creating a Custom Numeric Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649The Custom Format Placeholder Characters . . . . . . . . . . . . . . . . . . . . 649

    Formatting Date and Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653Creating a Custom Date and Time Format . . . . . . . . . . . . . . . . . . . . . . 655

    Formatting Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657

    22 Multithreaded Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659Multithreading Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659The Thread Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660

    Creating and Starting a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660Some Simple Improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663Creating Multiple Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664

    Determining When a Thread Ends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 666Pass an Argument to a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669The IsBackground Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671Thread Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674

    An Alternative Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677Locking a Static Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679The Monitor Class and lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679

    Thread Communication Using Wait( ), Pulse( ), and PulseAll( ) . . . . . . . . . 680An Example That Uses Wait( ) and Pulse( ) . . . . . . . . . . . . . . . . . . . . . 680Deadlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684

    Using MethodImplAttribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684Using a Mutex and a Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686

    The Mutex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686The Semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690

    Using an Event Synchronization Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693The Interlocked Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696Terminating a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697

    An Abort( ) Alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698Canceling Abort( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700

    Suspending and Resuming a Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701Determining a Thread’s State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702Using the Main Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702Multithreading Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703Starting a Separate Task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704

    23 Collections, Enumerators, and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707Collections Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707The Non-Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709

    The Non-Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709The DictionaryEntry Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713The Non-Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 714

    Storing Bits with BitArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730

  • xvi C # : T h e C o m p l e t e R e f e r e n c e

    The Specialized Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733The Generic Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734

    The Generic Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734The KeyValuePair Structure . . . . . . . . . . . . . . . . . . . . . . . . . 737The Generic Collection Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737The Queue Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754

    Storing User-Defi ned Classes in Collections . . . . . . . . . . . . . . . . . . . . . . . . . . 755Implementing IComparable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758

    Implementing IComparable for Non-Generic Collections . . . . . . . . . 758Implementing IComparable for Generic Collections . . . . . . . . . . 760

    Using an IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761Using a Non-Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761Using a Generic IComparer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 763

    Accessing a Collection via an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 764Using an Enumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765Using the IDictionaryEnumerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766

    Implementing IEnumerable and IEnumerator . . . . . . . . . . . . . . . . . . . . . . . . 767Using Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 769

    Stopping an Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771Using Multiple yield Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772Creating a Named Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772Create a Generic Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774

    24 Networking Through the Internet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777The System.Net Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777Uniform Resource Identifi ers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779Internet Access Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 780

    WebRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781WebResponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783HttpWebRequest and HttpWebResponse . . . . . . . . . . . . . . . . . . . . . . . 784A Simple First Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784

    Handling Network Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786Exceptions Generated by Create( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787Exceptions Generated by GetReponse( ) . . . . . . . . . . . . . . . . . . . . . . . . 787Exceptions Generated by GetResponseStream( ) . . . . . . . . . . . . . . . . . 787Using Exception Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 788

    The Uri Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789Accessing Additional HTTP Response Information . . . . . . . . . . . . . . . . . . . . 790

    Accessing the Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791Accessing Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792Using the LastModifi ed Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794

    MiniCrawler: A Case Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 795Using WebClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 798

  • C o n t e n t s xvii

    Part III Applying C# 25 Building Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 807

    What Is a Component? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 807The Component Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808

    What Is a C# Component? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808Containers and Sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808C# vs. COM Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808

    IComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809A Simple Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810

    Compiling CipherLib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811A Client That Uses CipherComp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811

    Overriding Dispose(bool) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812Demonstrating Dispose(bool) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 813Preventing a Disposed Component from Being Used . . . . . . . . . . . . 818

    Employing the using Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 819Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 820

    Demonstrating a Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821Are Components the Future of Programming? . . . . . . . . . . . . . . . . . . . . . . . . 823

    26 Creating Form-Based Windows Applications . . . . . . . . . . . . . . . . . . . . . . . . 825A Brief History of Windows Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . 825Two Ways to Write a Form-Based Windows Application . . . . . . . . . . . . . . . 826How Windows Interacts with the User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826Windows Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827

    The Form Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827A Skeletal Form-Based Windows Program . . . . . . . . . . . . . . . . . . . . . . . . . . . 827

    Compiling the Windows Skeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829Adding a Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830

    Button Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830Adding a Button to a Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830A Simple Button Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 831

    Handling Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 832An Alternative Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834

    Using a Message Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834Adding a Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837

    Creating a Traditional-Style Main Menu . . . . . . . . . . . . . . . . . . . . . . . 837Creating a New-Style Menu with MenuStrip . . . . . . . . . . . . . . . . . . . 841

    What Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 844

    27 A Recursive-Descent Expression Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845Parsing Expressions: The Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 846

  • xviii C # : T h e C o m p l e t e R e f e r e n c e

    Parsing an Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847Dissecting an Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848A Simple Expression Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851

    Understanding the Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856Adding Variables to the Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857Syntax Checking in a Recursive-Descent Parser . . . . . . . . . . . . . . . . . . . . . . . 865Some Things to Try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865

    A XML Comment Quick Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867The XML Comment Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867Compiling XML Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869An XML Documentation Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869

    Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 873

  • Preface

    We 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 longtime programming guru Anders Hejlsberg. C# is directly descended from two of the world’s 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. For example, both support distributed programming, and both use intermediate code to achieve safety and portability, but the details differ.

    Building on the strong foundation that it inherits, C# adds several important innovations that advance the art of programming. For example, C# includes delegates, properties, indexers, and events as language elements. It also adds syntax that supports attributes. Furthermore, C# streamlines the creation of components, eliminating the troubles associated with COM. One other point: Like Java, C# offers a significant amount of runtime error checking, security, and managed execution. However, unlike Java, C# also gives you access to pointers. 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 to the needs of today’s programmer. Nothing demonstrates this fact better than the release of version 2.0.

    C# 2.0 is the first major revision to C#, coming about five years after its initial 1.0 release. The intervening years have seen ever-increasing demands placed on the programmer. Applications have become more complex, and so has the environment in which they execute. C# has responded by adding a list of innovative features that make it easier for programmers to write more resilient, reliable, and nimble code. Here are three examples. Generics make possible the creation of type-safe, reusable code. Partial class declarations facilitate the coding of large classes by allowing their definitions to be broken into pieces. Anonymous methods streamline the coding of methods passed to delegates. In general, C# 2.0 contains many forward thinking features that make programming for today’s demanding environment a bit easier.

    xixCopyright © 2006 by The McGraw-Hill Companies. Click here for terms of use.

  • xx C # : T h e C o m p l e t e R e f e r e n c e

    This book is a comprehensive guide to the C# language, including those features added by C# 2.0.

    What’s InsideOne of the most challenging aspects of writing about C# is knowing when to stop! The C# language, by itself, is big. The C# class library is even bigger. To help manage this large amount of material, the book is divided into these three parts:

    • The C# Language

    • Exploring the C# Library

    • Applying C#

    Part I provides a comprehensive discussion of the C# language, including the new features added by version 2.0. This is the largest part in the book, and it describes the keywords, syntax, and features that define the C# language. I/O, file handling, reflection, and the preprocessor are also described in Part I.

    Part II explores the C# class library, which is also 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. This is the part of the library that relates most specifically to C#. Also covered are collections, multithreading, and networking. These are the parts of the library that nearly every C# programmer will use.

    Part III contains examples that apply C#. Chapter 25 shows how to build software components; Chapter 26 describes the construction of Windows applications using the Windows Forms library; and Chapter 27 develops a recursive-descent parser for numerical expressions.

    A Book for All ProgrammersThis 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 don’t 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 SoftwareTo compile and run C# 2.0 programs, you must use Visual Studio 2005 or later. Also, .NET Framework 2.0 must be installed on your computer.

    Don’t Forget: Code on the WebRemember, the source code for all of the programs in this book is available free-of-charge on the Web at www.osborne.com.

    www.osborne.com

  • For Further StudyC# 2.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#: A Beginner’s Guide

    To learn about Java programming, we recommend the following:

    Java: The Complete Reference, J2SE 5 Edition

    Java: A Beginner’s Guide

    The Art of Java

    To learn about C++, you will find these books especially helpful:

    C++: The Complete Reference

    C++: A Beginner’s Guide

    C++ From the Ground Up

    STL Programming From the Ground Up

    The Art of C++

    If you want to learn more about the C language, the foundation of all modern programming, the following titles will be of interest:

    C: The Complete Reference

    Teach Yourself C

    When you need solid answers, fast, turn to Herbert Schildt,

    the recognized authority on programming.

    P r e f a c e xxi

  • This page intentionally left blank

  • IThe C# Language

    Part 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 and Events

    CHAPTER 16: Namespaces, the Preprocessor, and Assemblies

    CHAPTER 17: Runtime Type ID, Refl ection, and Attributes

    CHAPTER 18: Generics

    CHAPTER 19: Unsafe Code, Pointers, Nullable Types, and Miscellaneous Topics

    PART

    Copyright © 2006 by The McGraw-Hill Companies. Click here for terms of use.

  • This page intentionally left blank

  • 1The Creation of C#

    C# is Microsoft’s 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 TreeComputer 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 world’s 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 ProgrammingThe 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. Using structured languages, it became easier to write moderately large programs.

    3

    CHAPTER

    Copyright © 2006 by The McGraw-Hill Companies. Click here for terms of use.

  • 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 today’s 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. Once a project reaches a certain size, it can become difficult to understand and maintain. Precisely where this limit is reached depends upon the program, the programmer, and the tools at hand, but it can be encountered with as few as 5,000 lines of code.

    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 a new programming language. Instead, it was an enhancement to an already highly successful language. This approach to language development—beginning with an existing language and moving it forward—established a trend that continues today.

    The Internet and Java EmergeThe 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 Java’s 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,

  • PART I

    C h a p t e r 1 : T h e C r e a t i o n o f C # 5

    PART IPART I

    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, finding a way to easily port a program 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 program’s 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.

    Java’s 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 were needed. Not only was this impractical, it was expensive. Java’s use of an intermediate language was an elegant, cost-effective solution. It was 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 attentions 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 the accepted substrata upon which new computer languages are built.

    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.

  • 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 mostly 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 Microsoft’s 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 world’s 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 used—and most widely liked—programming 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 start from scratch, 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, C# includes features that directly support the constituents of components, such as properties,

    FIGURE 1-1 The C# family tree

  • PART I

    C h a p t e r 1 : T h e C r e a t i o n o f C # 7

    PART IPART I

    methods, and events. However, C#’s ability to work in a mixed-language environment is perhaps its most important component-oriented feature.

    The Evolution of C#Following the original 1.0 release, C# has undergone two revisions. The first was version 1.1, which was a minor upgrade that did not add significantly to the language. The second is version 2.0, which this book covers.

    Version 2.0 is a major release. It adds many new features and fundamentally expands the scope, power, and range of the language. Along with many small improvements, C# 2.0 includes 14 major additions to the language. They are listed here:

    • Generics

    • Nullable types

    • Iterators

    • Partial class definitions

    • Anonymous methods

    • The :: operator

    • static classes

    • Covariance and contravariance

    • Fixed-size buffers

    • Friend assemblies

    • extern aliases

    • Method group conversions

    • Accessor access control

    • New #pragma directives

    Of these new features, the one that has the most effect on the language, and the most direct impact on programmers, is generics. Not only does it add an entirely new syntax element to the language, but it also greatly expands C#’s expressive power by enabling the creation of type-safe, reusable code. As a side-effect, the addition of generics has caused the Collections library to be greatly expanded.

    Throughout the course of this book each of the new features added by C# 2.0 is described in detail. As you will see, they further enhance an already rich and powerful language.

    How C# Relates to the .NET FrameworkAlthough C# is a computer language that can be studied on its own, it has a special relationship to its runtime environment, the .NET Framework. The reason for this is twofold. First, C# was initially designed by Microsoft to create code for the .NET Framewor