0 ratings 0% found this document useful (0 votes) 44 views 483 pages For Delphi Programmers
.NET 2.0 for Delphi Programmers by Jon Shemitz is a comprehensive guide aimed at Delphi developers transitioning to .NET, covering key concepts like managed code, the object model, and garbage collection. The book includes detailed comparisons between C# and Delphi, along with practical examples and source code available online. It serves as a resource for understanding the .NET framework and its application in Delphi programming.
AI-enhanced title and description
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here .
Available Formats
Download as PDF or read online on Scribd
Carousel Previous Carousel Next
Save .NET for Delphi Programmers For Later .NET for Delphi
Programmers
Jon Shemitz.NET 2.0 for Delphi Programmers
Copyright © 2006 by Jon Shemitz
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording, or by any information storage or retrieval
system, without the prior written permission of the copyright owner and the publisher.
ISBN-13: 978-1-59059-386-8
ISBN-10; 1-59059-386-3
Printed and bound in the United States of America9 87654321
‘Trademarked ames may appear in this book. Rather than use a trademark symbol with every occurrence
of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark
owner, with no intention of infringement of the trademark,
Lead Editor: Jim Sumser
Technical Reviewer: Hallvard Vassbotn
Editorial Board: Steve Anglin, Ewan Buckingham, Gary Cornell, Jason Gilmore, Jonathan Gennick,
Jonathan Hassell, James Huddleston, Chris Mills, Matthew Moodie, Dominic Shakeshaft, Jim Sumser,
Keir Thomas, Matt Wade
Project Manager: Sofia Marchant
Copy Edit Manager: Nicole LeClere
Copy Editor: Ami Knox
Assistant Production Director: Kari Brooks-Copony
Production Editor: Lori Bring
Compositor: Susan Glinert
Proofreader: Liz Welch
Indexer: Rebecea Plunkett
Artist: April Mi
Cover Designer: Kurt Krames
Manufacturing Director: Tom Debolski
Distributed to the book trade worldwide by Springer-Verlag New York, Ine.,2:
New York, NY 10013. Phone 1-800-SPRINGER, fax 201-349-4505, e-mailor
visit http://w. sor ingeronLine com,
Spring Street, 6th Floor,
-rs-ny@springer-sba.con, OF
For information on translations, please contact Apress directly at 2560 Ninth Street, Suite 219, Berkeley, CA
94710, Phone 510-549-5930, fax 510-549-5939, e-mail infofapress..con, or visit http: //w.apress.. com.
The information in this book is distributed on an “as is” basis, without warranty. Although every precaution
has been taken in the preparation of this work, neither the author(s) nor Apress hall have any liability te
any petson or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly
by the information contained in this work.
‘The source code for this book is available to readers at yww.apress.com in the Source Cade section,Contents at a Glance
Table Cross-Reference... Xvi
About the Author ..... xvill
About the Technical Reviewer xik
Acknowledgments ............5 OK
PHONES scsi ccemarineinerianeicnenean teem EROnIIME AEN ee er OIeNaT 7a
PART 1 Common Language Runtime
CHAPTER1 Managed Code .... ad
CHAPTER 2 The Object Model 17
CHAPTER3 = Garbage Collection ... 59
CHAPTER4 JIT and CIL.. 81
PART 2 C# and Delphi
(CHAPTER 5 ORT FYI sa ccercssnereeaneemmeennanenenes EP
CHAPTERG = C# Control Structures 00.2.0... 6... cece cence eee ee eee ees 125
CHAPTER7 — C# Objects 139
CHAPTERS —C# Interfaces and Delegates .............. 06. ceeeeeeeeee 173
CHAPTERS «= CHTOPICS 0... eee ee cence eee nett nnn eens 201
CHAPTER 10 Delphi for NET ....... JAAN RE NITY 221
PART 3 The Framework Class Library
CHAPTER 11 Strings and FilES «6.00.6... cee ee cece eee eee nee een eee enen 257
CHAPTER 12 Collections .......... 0... covet eee cee ee eee 305
CHAPTER 13 Reflection......... Wnaeeneeens
CHAPTER 14 Serialization and Remoting .
CHAPTER 15
WinForms Basics ..........000eeescseeeeeenneee tee eee eeeevi
CHAPTER 16
CHAPTER 17
CHAPTER 18
PART 4
‘APPENDIX 0
‘APPENDIX 1
‘APPENDIX 2
‘APPENDIX 3
‘APPENDIX 4
APPENDIX 5
INDEX
Graphics wee . . . 301
Threads and Synchronization 413
AME sercecsnteaneseseati 439
Appendixes
Unsafe C# Code 457
Nunit ... 465
Assembly Loading and Signing . 473
Configuration Files ...
Glossary
BibliographyContents
Table Cross-Reference...
About the Author .
About the Technical Reviewer
Acknowledgments .. .
Preface ..
PART 1
CHAPTER 1
CHAPTER 2
xvii
xvlil
Common Language Runtime
Managed Code .....
Beyond Delphi ......
Intermediate Code .
Garbage Collection .
Run-time Checking .
Checked Casts
Pointer Arithmetic.
Unsafe Code .. mM
Language Independence 13
Common Type System .. BCE RESETS tk
More Jobs 16
Key POMS cies eesciianasaaeeweaireanenreneneesabeaa 16
The Object Model 7
Farther Beyond Delphi . 17
What's New 19
Generics. +19
Single Object Model 28
No More Globals
Attributes...
Nested Ciasses
Type nitializers...
Sealed Classes and Sealed Methods
viiCONTENTS
CHAPTER 3
CHAPTER 4
What's Different x
Reference Types vs. Value Types. 2
Strings
Arrays.
Delegates.
Namespaces .
Enums ...
What's Missing
Subranges
Array Types... .
Sets
Metaclasses PED ‘ 4B
Common Language Speciation. 52
CLS Fules ... 53
Cross Language Programming .. 55
Key Points ..........06 58
Garbage Collection ... 59
Performance - 60
Detecting Live Data . 63
Pathological Cases . 64
Finalization 7 - 69
Disposing and Finalizing ... . . .70
Disposing and Not Fralzing 3 72
Complications . TR
Large Object Heap -73
Self-Tuning .. 74
Multithreading . 15
Multiprocessors. -16
Weak References . aT
Key Points .79
MT ANG CL sissrssccissenimescermaaaranrwne evageel
NET Is Not Interpreted . . 81
Real Pointers... + 82
Demand Loading 82
Code Quality ...... 83
Injining and Properties .. . wut
PRICONDIGIM :escscs ve pccmrese ramen oe BSPART 2
(CHAPTER 5
CHAPTER 6
CONTENTS
JIT Benefits
Productivity ....
Portability.
GIL: vesanwe te
Type-safe Assembler
ClL and the CLR
Actual CIL...... ‘
Expressions... . 92
Logical Operations 94
Methods and Results 95
ILDASM
Key Points ..........+6 103
C# and Delphi
C# Primitive Types .... beset tect eteeten eens ens 107
Types and Expressions . .. ..107
Aliases for System Types. 108
Numeric Literals. . 109
Numeric Expressions .... 110
Operators... wee 1
Assignment Operators 113
The Conditional Operator . 114
The Null Coalescing Operator . ott
The Increment and Decrement Operators . 115
Operator Precedence .... 116
Strings and Characters . 47
AITAYS oes eee 119
Enums . 120
Boxing . 122
Nullable Types .
Key Points ..
C# Control Structures ...
Blocks and Statements 125
Conditionals ...... 126
The if Statement....... 127
The switch Statement. . 127CONTENTS
CHAPTER 7
Loops saa
The for Statement......
The foreach Statement.
The while Statement
The do Statement. .
Exception Handling .
Special Blocks ....
The us ing Statement
The Lock Statement ....
Key Points 2........005
C# Objects ........
No Headers
Generics ......
Inline Types .. a
Constraints ............
C# Object Types
Access ....
Modifiers
Fields
Static Field:
Constant Fields
Read-only Fields.
Volatile Fields .
The new Modifier .
Methods .........
inheritance . .
Polymorphism .
Properties ..
Indexers
Mixed Access ....
Parameterized Properties.
Constructors .
Optional initializer.
Default Constructors. ........
Value Types
Finalizers
128
129
130
132
132
133
2 134
2 134
136
137
139
139
141
142
143
144
145
47
148
148
148
149
150
150
151
157
158
199
161
++ 162
+ 162
163
165
-. 168
169
- 169CHAPTER 8
CHAPTER 9
CONTENTS
Operator Overloading . % ..170
Background and Warning . 1m
Infix Operators. 172
Type Conversion .
Truth........
173
175
Nested Types .. 175
Which Object Type? . 176
Key Points ............ 7
C# Interfaces and Delegates 179
Interfaces ...... cece 173
iterators ... 182
Delegates .. 186
Events newman 188
Delegate Value Equalily.............. wee 190
Anonymous Methods... 00... 191
Covariance and Contravariance . 193
Asynchronous Execution . 2 195
Key Points + 199
C#Topics ....... 201
The Main Method ...
Namespaces ....... 201
Name Resolution. 203
Aliases ...... 204
Namespace Versionin. 206
Attributes ........
Attribute Targets. :
Compile-time Atiributes. 213
The @ Escape .
Preprocessor Directives
Conditional Compilation
Warnings and Errors.
Folding Regions...
Partial Classes .
Key Points ..
xtCONTENTS
CHAPTER 10 Delphi for .NET . : . 221
Adapting to Change . .. 221
The Object Model . + 222
Other Language changes 5 229
NET Platform Support .... «236
Obsolete Features. .... 246
Win32 and .NET Differences. 2ar
Delphivs. CH. 250
Delphi Language Highlights, me
C# Language Highlights. 262
Key Points ............ 253
PART 3
CHAPTER 11
The Framework Class Library
Strings and Files ....
Learning the FCL....... vec eceees beste eeeeeeeee es 287
Strings 259
The String Class 260
Concatenation Methods ++ 260
The Format Method 262
Substrings ... 267
Compare Methods .. 268
Search and Replace 269
Split and Join ..... * 270
Miscellaneous Methods. +272
Constructors .
Interning
Sting Conversions
The StringBuilder Class .. 278
Regular Expressions ... at
Regex Invoduction .2mT
The Regex Engine. . 2 278
Regex Pattern Language . «280
The Regex Class .
Fils oo... ccc : :
File System Information Seereerererterrert) ++ 290
File 10. sees seuss . 301
The .NET Console . 304
Key Points .... 304CHAPTER 12
CHAPTER 13
CONTENTS
Collections . . + 305
Arrays... 306
Copy... 307
Sort... 307
Search an
Miscellaneous . 312
Lists oo. cee 313
Late-bound Lists. +313
Early-bound Lists . 315
Hash Tables ........... 316
Late-bound Hashes eS
Early-bound Hashes RRA " ‘ 319
Stacks and Queues . .. x a sera ten 319
Enumerations . 320
Fundamentals . 321
Threading.
Multiple Enumerator: 324
Delegates. 325
Iterators ....... 326
Other Collection interfaces 326
Key Points
RGLECHION: cresrerecsmmne rE 329
Run-time Type Information ...
Type Values ....... we
The typeof() Operator.
GetType
Get Type by Name
Type Details .......
Member Access
Type Metadata
Assemblies
Emit ...
Key Points .CONTENTS
CHAPTER 14
(CHAPTER 15
CHAPTER 16
Serialization and Remoting . . . 353
Standard Streaming .
XML Streaming .
Different Representation .
Different Technology ....
More Attributes
‘SOAP Bubbles .
NET Remoting ...
Interprocess Communicatio - + 364
Application Domains. -. 368
Key Points 372
WinForms Basics .. 373
Form Design and Loading 374
Docking .... 376
Events .... 379
Event Multiplexing 379
Low-level GUI Access. 380
Threads .... 381
382
382
= 388
The Small Stuff
The Biggest Small Stuf
VCL-to-FCL Map...
Key Points ...........5 389
Graphics 391
Familiar, but Not Identical .... 391
GDI+ Details
Colors.
Pens...
Brushes
Fonts and Text.
Bitmaps .....
Paths and Regions
Printing,
Key Points
+410
24CHAPTER 17
CHAPTER 18
PART 4
APPENDIX 0
APPENDIX 1
APPENDIX 2
CONTENTS
Threads and Synchronization : : : 413
Thread Basics ......... a3
Threads and Processes...
Synchronization... .
NET Threads . aig
Thread Priority . azz
Foreground and Background Threads .. 422
Thread-local Storage .... 598 423
Aborting and Interrupting Threads . . 424
Synchronization ........ 426
Managed Locking........... 428
The .NET “Memory Model” macrotis + 429
Interlocked Access * # 431
Wait Handles . 432
Thread Pool 435
Worker Thread: 436
Wait Callbacks. 437
GUI Issues . 438
Key Points . 438
UML: iecuyprssseremnnnmnnearmernsenamrnsseenssatT 439
LR cc cceccemnnimcnoncen aameninennin sxermmn 439
XML Reader ... wee M43
The XML DOM = 446
XSLT oo... ee . cs : see AAT
Key Points syssresceceyversnnversrecnvernuayenn oexnaree dil
Appendixes
Unsafe C# Code «2.22.6... aay AST
NUNIT eccrerveravers SRNR MUN RUT ORES 465
Assembly Loading and Signing ..................00606 473CONTENTS
‘APPENDIX 3
APPENDIX 4
APPENDIX 5
ONDE oi veieeeae
Configuration Files
Glossary .........
Bibliography
art
.. 479
2 485
489Table Cross-Reference
Table 2-1. Set Operators and Their Bitmapped Equivalents ........ 6.0... 06.05 66.48
Table 3-1. Results from the Chapter3\MakingTrouble Project... . . 65
Table 5-1. System Types ..... 108
Table 5-2. C# Operators That Are Different Than m Dee Oper wae d12
Table 5-3. Operator Precedence ......... 2.116
Table 5-4. | Symbolic Character Escapes .......... aca le
Table 5-5. Hexadecimal Character Escapes. : 118
Table 7-1. Constructor Syntax . 163
Table 8-1. Interface and Delegate Tradeotts. «188
Table 10-1. Obsolete Features . RS aa +246
Table 10-2. Delphi Language Features 251
Table 10-3. Ci# Language Features . 2.0.6... eee eee eee eee te ee eee e252
Table 11-1. Standard Numeric Formats . . + 265,
Standard DateTime Formats +++ 266
Miscellaneous String Methods . 272
Regex Patter Characters . deaweeweee ce 2BI
Perl-compatible Predefined Character Classes x i ee]
Two-character Regex Assertions . ae + 283
Table 11-7. Default Regex Behaviors, and Their RegexOptions Overrides ewes O07
Table 11-8. Selected Path Members « wise wav +6 299
+ The Five Main Collection Interfaces . +827
AFew Type Categorization Members ..... . 344
FCL Equivalents for Common VCL Constructs » 389
ARace Condition ....... ++ 416
Deadlock 1 AB
Table 17-3. No Deadlock . Kinewanie aa eee weanaaw eines ATO
Table A1-1. Class (Test Fixture) Attributes ...........s0.0sccsseeceess0+00-470
Table A1-2. Method Attributes 470
Table A1-3. NUNIASSEMIONS 0.2... cece ee eterna retinas ce MFDvill
About th
e Author
MON SHEMITZ has been programming since he was 12, when he learned
Focal on a PDP-8. He's been programming professionally since he
graduated from Yale in 1981, andhas done everything from shrink-wrap
programming to consulting. Jon has used Borland Pascals since Turbo
Pascal 1, and hasbeen doing .NET programming in C# since 2002.
Thisis Jon's second book: he’s written dozens of programming articles;
contributed to four other books; and has given programming talks on
two continents.
Jon does contract programming, consulting, and training—you can contact him at
\wiw.nidnightbeach.com.About the Technical Reviewer
HALLVARD VASSBOTN is a senior systems developer at and partial owner
of Infront AS (www.infront.no), developing state-of-the-art real-time
financial information and trading systems (ww. theonlinetrader .con).
Hallvard has beena professional programmer since 1985, and has written
numerous articles for The Delphi Magazine and tech edited several
popular Delphi books.
You can read his technical blog at hallvards. blogspot .con/
Hallvard lives in Oslo, Norway, with the three diamonds of his heart,
Nina, Ida, and Thea, You can reach him at hallvardvassbotn@c2i .net.
xixcs
Acknowledgments
Thastisonrescsconsatecoranon sir ouveca your: wiseaxrenaenaen poeablawanians
the help of many talented people—most of whom I've never met.
Dan Appleman and the editorial board at Apress had the good taste to agree thata book
about .NET for Delphi programmers would sell better than the Delphi for NET reference that
they originally agreed to publish. More importantly, they've been willing to wait for a book
that’s longer and later than they originally expected. Sofia Marchant, my project manager, hes
been answering my questions for nearly three-and-a-half years, and she put togethera produ
team that smoothly and painlessly turned my 4 meg of Word and TIF files into a printed book.
Ami Knox, the copy editor, made my punctuation and capitalization consistent, and caught
awkward phrases that made it past all my rewrites; I'd especially like to thank Ami for the extra
effort involved in dealing with my ‘scare quotes.’ Liz Welch, the proofreader, did a great job
transferring the syntax highlighting from my manuseript to the printed page, and she also
caught several mistakes that made it past both Ami and me.
Google made it much easier for me to answer various questions. Without Google, the
research would have taken much longer, and I might never even have found some of the more
interesting details. VMWare generously supplied me with a [ree “authors copy” of VMware
Workstation, which made it much easier (and safer) to install and uninstall beta software. My
orthopedist, Dr. Howard Schwartz, was very patient with my impatience when a bike accident
tore shoulder ligaments and disabled me for three months near the end ofthe first draft.
Thave the good fortune to live with three fine writers—my partner, Tané Tachyon, and our
sons, Sam and Arthur Shemitz. All three of them have had to put up with innumerable problem
paragraphs, and inevitably made good suggestions that helped move things along.
Weyert de Boer, Mark Boler, Marcel van Brakel, Alessandro Federici, Mare Hoffman,
Chuck Jazdzewski, lan Martens, Jon Skeet, and Danny Thorpe all read drafts of various chapters.
‘Their comments helped improve the book, and their positive feedback helped keep me working,
I'd particularly like to thank Jon Skeet and Marcel van Brakel. Jon helped me understand
the .NET memory model Chapter 17) and how it affects interprocessor synchronization, Marcel
read every chapter at least once, and made detailed comments on most of them. I’ve benefited
greatly from his deep knowledge, his helpful suggestions, and his uncanny ability to find every
point where I waved my hands vaguely and hoped no one would notice.
Finally, I can’t say enough about Hallvard Vassbotn, my technical reviewer. This project
Was much more work (and took much longer) than he could possibly have anticipated when he
signed on, yet he read every chapter two or three times —and caught errors and made suggestions,
each time. Hallvard also wrote the Delphi syntax chapter when I was considering dropping itafter
my bike accident. I've enjoyed working with him, and have been thoroughly impressed by his
intelligence, energy, and diligence. Naturally, any mistakes that remain are entirely my fault.
April 2006
Santa Cruz, Californiaa
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.PREFACE
Thatis, if | say that Benjamin Franklin said “Thank you.” I'm saying that Lam 100% sure
that Benjamin Franklin said “Thank you" on at least one occasion. | use double quotes when
V'm actually quoting something I've read or heard. By contrast, if | say that Benjamin Franklin
said ‘Those who will sacrifice Freedom for thesake of Security will soon lind they have Neither,
1'm saying that Benjamin Franklin said something like that. [ use single quotes when I'm para-
phrasing, or when ['m using slang or a neologism.
The Sample Code
‘There are over 150 sample projects mentioned in this book. For the most part, I only print the
few most interesting lines of each. In some cases, I don'teven do that—I describe a technique,
and refer you toa sample project for the details. To run the projects and/or read the code that
Idon't print, you'll have to download the appropriate zip file from the Apress web site, and
install it on a machine with a NET development environment.
You can get the code by going to the Source Code section of the Apress web site,
wii. apress.com, where you'll find complete download and installation instructions. [urge you
to download the sample code. Reading the code and pressing H1 on variousidentifiersis a great
way to dip into the NET documentation. More importantly, while I've made every effort to
keep the book self-contained so that you can read it away from a computer, some techniques
are best grasped by experimentation, Using my working code as a starting point can be very
helpful here. (Most of the projects are just snippets that demonstrate a single point, but there
are a few that contain code you may wantto borrow.) All the sample code—from the code that
demonstrates various useful techniques to the utility units in my common directory—is distributed
under a license thatlets you use my code in any way you like, so long as you leave my copyright
notice in the source code.
xxia
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.Managed code is the foundation for all of .NET. Managed code combines type-safe,
compiled code with fast garbage collection. This combination enhances programmer
productivity and eliminates common security flaws. Garbage collection prevents
dangling pointers and reduces memory leaks, and garbage collection encourages you to
treat objects as simple values. Type safety blocks common program failure modes like
buffer overruns and miscasting. What is special about NET is that it delivers these
benefits in a language-neutral way.
Beyond Delphi
You're mare productive on NET
‘Do you remember when you first used Delphi? Suddenly, everything became much easier. Reams
of boilerplate code were sweptaside, dramatically increasing your productivity. Concepts that
were once hidden in Windows APIs were exposed in object hierarchies, making it easy to do
things like hide and unhide groups of controls.
‘Thal productivity increase made it worth unlearning old habitsand learning a new library.
Much the same experience is in store for you when you move to .NET. Youhave to give up
native code, you have to come to grips with garbage collection, and youhave to learn abignew.
object-oriented run-time library—but the payolfis a big productivity increase.
When you use anative code compiler (like Delphi 7, Kylix3, or Delphi 2006's Win32 person-
ality), your source codes translated directly to native Intel object code, which can tun directly
ona Windows or Linux machine. By contrast, Delphi for .NET and all other NET languages
compile to CIL, or Common Intermediate Language. CIL is the NET version of Java's byte codes,
and must be compiled at run time by a Just In Time (JIT) compiler. Though this may seem like
an obviously foolish thing to do, you'll seein this chapter and in Chapter 4 that IT compilation
isn’t particularly expensive and actually offers significant advantages.
Versions of Delphi that compile to native code use manual heap-based memory manage-
ment. Your code calls library routines that allocate memory from a linked list of free memory
blocks, and your code should free all memory when it is done with it. NET uses garbage collection,
which means the system automatically frees memory when itis no longer being used. This
chapter discusses how garbage collection makes your code mote reliable. Garbage collection
also makes your code much smaller and clearer, which in turn makes it easier to write and to
read. Chapter 3 has the details of the garbage collection mechanism and costs.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER | = MANAGED CODE
Garbage Collection
Garbage collection makes your life easier
‘The CLR calls your application's main procedure via the just In Time compilation mechanism,
and regains control briefly to jit each method as it’s first called. Over time, the CLR is called
upon to jit code less and less, as the program’s working set is loaded and compiled. However,
the CLR also regains control whenever your application requests memory.
When your NET code allocates memory by creating an object or buildinga string value,
you call CLR routines that carve off another chunk from the front of big block of memory that
the OS gave your application. When you've allocated “enough” memory, the CLR will decide to
do garbage collection on the most recent allocations. The garbage collection algorithm takes
advantage of the way that after “enough” allocations, “most” blocks are no longer being used.
Since there isn’t much live data, it doesn’t cost all that much to find all the places that refer to
live data. And, while it’s not cheap to slide each block of live data down to the bottom of the
memory partition, and then change each reference to the moved data to point to the block's
new location, atleast you don’t have to de this for too many live data blocks. After the CLR has
packed the live data, all the free memory in the partition is again in one contiguous block. This
contiguity means that the overwhelming majority ofallocations, the ones that don’t trigger a
garbage collection, are very cheap.
You'll find more details on how garbage collection works in Chapter 3.2 What's important
here is the way garbage collection frees you froma lot ofmemory management overhead. The
system scavenges memory once itis no longer being used, so you never have to explicitly free
the memory that you allocate. In turn, you no longer have to worry that the system will sun out
of room if you don’trelease every byte you allocate assoon as you're done with it. What’s more,
you never again have to deal with the nasty, hard to track down memory corruption bugs that
spring from using some data that’s already been freed and reallocated.
Thisis the sort of problem you get with dangling or tombstone pointers. Dangling pointers
and tombstone pointers are two different names for the same thing: a dangling pointer is one
that no longer connects to anything: a tombstone pointer is a pointer to a dead data structure,
one that has already been freed. This is an easy state to find yourselfin with heap-based, unman-
aged code—all it takes is freeing an objectin one place while you still have a live reference to it
somewhere else.
Asking a dead object to do somethingis a common cause of memory corruption. You may
get lucky and get an access violation, but the odds are that the old address is still within your
program's address space. Thatis, you are essentially treating a random value as a pointer. The
very best result you can getis for your program to crash right away, perhaps because you are
not pointing to the start of an object, and the memory your code ‘thinks’ isa virtual method
table is pointing to data, not code. However, it’s entirely possible that you will scramble the
Internal state ofsome data structure. Sometine later, When you use the scrambled compo-
nent, you will get garbage results or the program will crash. This is a bad outcome, because
thereis no obvious connection between the symptom and the real cause: a bad cast here results
in mysterious behavior there, some indeterminate time later. These “Mandelbugs” can be very
2. Along with discussion of the (rare but not nonexistent) type of code that tums the garbage collector's
design decisions against itself, and forces the system to spend all its time garbage collecting,a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 1 = MANAGED CODE n
Unsafe Code
Interfacing with legacy code may need pointers
-NET will let you use pointers and pointer arithmetic, but code that does so is considered
unsafe code. Safe code is cade that always follows type-safety riules—no unchecked casts, and
no pointer arithmetic. Safe code may he buggy code, but bugs in safe code are comparatively
easy to detect. Bugs in safe code give wrong answers, not scrambled memory.
Because all NET programs are compiled to strongly typed CIL instead of untyped native
machine language, it’s possible to verify that a program contains only safe code. Verification is
the process of reading an assembly's code, and programmatically proving thatit doesn’t break
type-safety rules. (This is much like the way a Delphi compiler bans things like assigning a
TForn value to an integer variable.) You can do this with pever ify, a tool that comes with the
.NET SDK that will verify a whole assembly, and will either assure you thatit is safe or will let
you know which methods contain unsafe code. .NET can also verify code each time itis JIT
compiled from CIL to native code, and can be set to refuse to run any unverifiable code.
That is, whether or not your code is actually verified at run time is a matter of which
permission set isin place. \ permission set is a collection of privileges—things an assembly is
allowed to do. Minimally trusted assemblies have no access to theregistry and can’t use reflection
to read metadata (metadata is NET’s version of Delphi's RTTI, and I talk about it both later in
this chapter and again in Chapters 4 and 13); fully trusted assemblies have full access to the
registry, metadata, and the local file system. Fully trusted assemblies can even run code that
fails verification, When an assembly is loaded, NET decides which of the system’s permission
sets apply toit, based on various bits of “evidence” like where the assembly ‘lives,’ who wrote
it, and soon. (Configuring permission setsis an administrative issue that’s beyond the scope of
this book.)
So, programs like Chapterl \PurTest.dpr
progran Ptriest;
{SAPPTYPE CONSOLE}
{SUNSAFECODE OW} // DfN will not generate unsafe code without this switch
const
Az array[0..2] of integer = (1223, 1224, 1226);
procedure Unsafe; unsafe;
/1 DAN will not generate unsafe code outside an
unsafe” routine
var
* integer; // pointers are unsafe
begin
Poss @ ALO]; // this Line generates @ warning
Inc(P); // this line connot be verified
Wiriteln(P*); // this line generates a warning
end;a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 1 = MANAGED CODE
Beyond the header translation tax, in unmanaged environments like Win32 and Linux,
every object-oriented language uses its own abject layouts and calling conventions. Calling
methods or passing objects from language to language is difficult,” or even impossible. This is
Why the Win32 API has never moved beyond alowest common denominator approach, a series
of ‘flat’ C functions that every different language can call, and upon which every different
language can layer its own incompatible set of objects. When native Delphi code manipulates
aTFont, not only does just about every action have to get translated to something that passes
alFont to a Win32 API function, it's also doing something very Delphi-specific: Delphi code
can't pass a TFont toa Win32 API function or to VB or MEC code, nor ean Delphi code expose a
Tront to a plug-in written in VB or MEC.
In .NET, objects are primitives, at nearly the same level as an integer, double, or string.
Every NET language uses the same layoutfor fields and object description tables as every other
.NET language. Every NET language uses the same calling conventions as every other NET
language. Every .NET language can use any object created in any other .NET language.®
This means that the run-time library can be object oriented from the ground up; objects
and exceptions aren't layered on top ofa flat run-time library. Delphi code can call C# methods
directly, without translation. Delphi code can create C# objects directly—both the APLand the
application use the same memory management code—and can embed the C# objects in Delphi
data structures or pass them as parameters to Framework Class Library (FCL) methods.
Delphi code can use the objecis that various FCL methods retum, without any wrapper code
or header translations. Delphi code can create specialized descendants of C# library classes.
Exceptions raised by a FCL method written in C# can be handled in the Delphi code that made
the FCL call.
A Font instance (the FCL version ofa TFont) can be passed between code written in Delphi
and code written in VB or C#. Your code can serve orbe served, or even both
7. You may need to manually insert pad fields to compensate for different field alignment strategies, This
is often hard to get right even when you know exactly which compiler generated the “alien” code—and
is virtually impossible to do in a way that will work with multiple compilers or compiler versions.
8, This is actually a bit of an overstatement. Some NET languages have primitive types that other .NET
Janguages do not, For example, Visual Basic does not have unsigned integers, and very few (if any) other
Janguages understand Pascal's bitmapped sets. Chapter 2 discusses the Common Language Specification
(CLS), which details the primitive types that a first-class NET language must understand, Also, some
-NET languages (like JScript) can “consume” objects but not create them. The proper, if nitpicky, thing
tosay is “Every .NET language can use any CLS-compliant object created in any other first-class.NET
language.”
Do note, however, that CLS compliance isa matter of field types and member names, not a matter of object
layout or metadata creation. All NET objects have the same internal structure, and all .NET objects are
described in the metadata. The distinction between objects that are CLS compliant and objects that
are not CLS compliant is nowhere near as strong and sharp as the distinetion between a Delphi class.
and a Delphi object (let alone the distinction between a Borland Delphiclass and a Microsoft C++
class), which aré laid out differently and which act differently. An object that is not CLS compliant is a
perfectly normal abject that happens ta have some members that some languages can’t understand,
not an object constructed according to different rules.
6a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL
What’s New
Relatively little is really new
While the FCL is quite large and will take time to learn, the NET object model itself doesn’t
contain all that much besides 2.0’s generics that’s genuinely new to a Delphi progcammer:
+ Every bit of data descends from Object, and this does make some things easy that were
complicated before, but many people find that this only affects their day-to-day coding
bymaking the NET collection classes much more universal than their Delphi equivalents—
because a single INET collection class can hold any value, .NET doesn’t need anything
like Delphi's constellation of specialized TList descendants.
* Object orientation is taken to a new level, with the abolition of stand-alone procedures
and functions, but you'll find that this doesn’t really change all that much, besides adding
alot of dots in method names?
* Static methods are not quite like Delphi’s class methods, and static members (class
variables) are something Delphi should have had ages ago, but these are not the sort of
major innovations that take pages and pages to explain and months to master.
* Nested classes can make your code simpler and more modular but, as with most data
hiding syntax, their benefit is a subtle matter of bugs prevented, not a radical matter of a
new abstraction that tames previously insoluble problems.
+ Sealed classes and sealed methods will probably take you a while to learn to use appro-
priately (the temptationis to seal too much, just as it’s easy to make too much private),
but the concept is pretty simple.
In fact, some people dismissively say that there's nothing new in .NET, that it's just a
repackaging of existing technology. To some extent, they're actually right—but they're still
missing the point. NET may contain little that hasn't been seen before—but it does it all so
well. The CLR works well; the language independence is really good; and the library design is
clean and comprehensive. The NET designers took all the best ideas they could find, and learned
all the lessons that they could from other people’s implementations.
Generics
CIL that supports generics that look like C++
Chapter I describes how and why .NET programs are compiled to CIL, anintermediate language,
instead of to native code. CiL. 1.9 isa strongly typed machine language that supports interfaces,
exceptions, single inheritance, and boxing.
CIL2.0 adds intermediate language representations
2. Delphifor NET (DIN) supports “flat” functions by creating special classes, one per unit, that define flat
function and gobal vatiables as static members. Within DIN, you can refer to these unit class members,
\with undotted names, just as in native cade; from other languages, you must use qualified (dotted)
names to referto the public members of a unit class.
19a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL 23
return Result;
}
public static T[] ToArray( params LEnumerable[] Data)
{
return ToListeTs (Data) .ToArray();
a;
}
This class, from the Common\Shemitz. Utility C# project. isa closed, staticelass. The class
has no type parameters. But both methods are open methods that take type parameters. You
might use it as
int[] Concatenated = Concat.ToArray(
new int(] { 1, 2, 3},
new int{] { 4 },
new int{] { 5 }
Nullable Types
As you'll see, C# has the endearing habit of baking system conventions into its syntax, and
enforcing patterns with its grammar. For example, 2.0’s new SystemNullable structure is
exacily equivalent to a T?. The two forms are interchangeable, and either form turns a value
type into a nullable type. A bool? is exactly the same as Nul lablecbool>: a nullable bool that can
be true, false—or null.
Thatis, a nullable value acts much like a normal (nonnullable) value of its base type, except
that you can setit and compare it to nuL1 (nul is C#’s equivalent of Delphi's Nil} Thus, every
possible base type value isa possible nullable type value, but not vice versa: you can set a
nullable type toa base type value, but you cannot seta base type to a nullable value—you have
to cast it, first. For example,
bool? NullableBool;
bool Nornal3ool = true;
NuLlableBool = null;
NullableBool = Normal800l;
NormalBool = (bool) NullableBool; // raises an exception, if NullobleRool == null
Tip Nullable types let you have unset values without having to reserve special flag values, For example,
you can make any enum into a nullable enum. And you can make any integer or float into @ nullable number,
And you can have tristate booleans—true, false, and unset.
5, You can't declare a nullable reference type like a string?—a reference type can already be set to null.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL
Finally, you will often have to implement LEnumerable and/or IenunerablecT>. In many
cases, you will just pass on an existingimplementation. (For example, an ArrayList can be
enumerated via IEnumerable, while a List¢T> can be enumerated via IEnumerable.) In other
cases, you have to actually implement LErumerable by hand, C# 2's new iterator functions
mean that manually enumerating a collection is easierin 2.0 thanin 1.0—once again, Chapter 12
has the details.
No More Globals
‘Most names are qualified, with dots in them
‘The universal typing of the NET Object class comes into play in low-level code that you
will often use without really noticing. Probably the most noticeable change that .NET
makes to your programming style is that everything belongsto a (class, record, or enumerated)
ype. Global constants and variables become static flelds, so that, eg., global constant like
Delphi’s PathDel im becomes the DirectorySeparatoxChar member of the Path class, or Path.
DirectorySeparatorChar, Similatly, ‘flat’ functions like Delphi's Trin and Copy become the
instance methods String. Trim and String. Substring, and code like Trim(ThisString) becomes
ThisString.Trim().
Simple examples may make this move seem distincily retrograde. Short, simple names
have become much longer. However, you can't have all that many short, simple names. Before
long, you end up with long, concatenated names, and DateTimeToString or DeleteFile aren't
all that much shorter than DateTime. ToString and File.delete.
Ifanything, the dotted names are a bit easier to read, as the dot provides a visual break in
the middle of the long name. What's more, making all code into methods encourages unity in
naming: instead of sometines calling Tr inStr ng and other times calling Stu ingTz1n, every
method is called as noun. verb
Static Fields
Static” has not been a Delphi keyword, but in the Delphi world “static” has been contrasted
h “virtual” or “dynamic.” That is, we have spoken of a “plain,” or early-hound, method asa
“static method.” An early-bound method is one whose address can be determined at compile
time, based on the declared type of the variable that you use to call the method. Early-bound
methods have been contrasted with virtual, or late-bound, methods, which are looked up at
run timein a method table
The CTS uses a somewhat different nomenclature. NET conventions reserve “late bound”
for talking about Reflection, .NET’s version of Delphi's RTI (Chapter 13), and an early-bound
method is usually referred to as an instance method. Following G usage, “static” applies to
duration and scope, not to method address determination
In C,a lacal static variable is like a local “typed constant” in Delphi—a statically allocated
variable that's private to a function. A local static variable isa local variable that retains its,
value from call to call, rather than being allocated on the stack and automatically going away
when the function retusns.A global static variable is only visible within the declaring file.
By analogy, in C+ +a static field is a variable associated with a class, not with any particular
instance. Thats, it'sa variable allocated at compile time:a static field exists before any instances
of the class have been created; there's only one copy of the field, no matter how many instances
of the class exist; and a static field persists even after all instances of the class have gone away.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL
Do not confuse nesting with inheritance! Like any other class, nested classes inherit directly
from Object by default, but can explicitly descend from any class that is visible at the point the
inner class is declared. (Yes, this includes another inner class.) A nested class has only those
members that it explicitly declares or explicitly inherits—a nested class does not automatically
inherit anything from its outer class.
What a nested class does get from its outer class is privileged access. Methods of an inner
class have the same access to members ofits outer class as the outer class’s members do. That
is, an inner class's methodscan access any ofits outer class'sstatic private members and, given
areference to an instance ofits outer class, an inner class’s methods can access any ofits outer
Class’s private instance members
Itis very common for instances of inner classes to contain a private reference to an instance
of their outer class, so as to provide a specific ‘view’ of their ‘owner.’ Aninner class's reference
to its ‘owner is usually set in its constructor, as in the Chapter2\NestedClasses Delphi project:
constructor Outer-Tnner.Create(Ouner: Outer);
begin
inherited Create;
Self.Ouner := Owner;
Reset;
end;
Syntactically, an inner class type is just another element of the class definition, on a par
with fields, properties, and methods. Thus, an inner class can be declared as public, private,
protected, or {in C#) internal—just like any other class member. When an inner class is declared
as private (strict private, in Delphi) or protected, no code outside of the outer class (“outside
code”) can create the inner class or call any of the inner class's methods. Conversely, when an
inner class is declared as publ ic, any code can create and refer to aninstance of the inner class.
‘This is relatively uncommon, but itcan make sense for a cass to declare a collection as a public
inner class, so that you would refer to, say, a collection of widgets as a Widget. Collection
instead of a WidgetCoLlection.
Within an inner class, member visibility controlsaccess to the inner class's members in the
normal way. The visibility of an inner class has nothing to do with the visibility of its members!
Thus, though private members ofthe outer classare visible to all of the inner class's methods,
(strict) private members of an inner class are not visible to its outer class's members.
Note Evena private inner class must have either a constructor that is visible to the outer class, or a
static method (that is visible to the outer class) that calls a private constructor.
When anested class is (strict) private or protected, it can only be created by a method of
its outer class (or bya method of a ‘peer’ class nested within the same outer class), and outside
code cannot directly call any of the inner class's methods. However, when a public method of
the outer class returns an interface, the result can actually be an instance of a private inner
class that implements that interface. Outside code can then call methods and read and write
aa
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL
What’s Different
-NET contains a lot of new twists on familiar concepts
It’s been over 30 years since Brooks told us to “plan to throw one away; you will, anyhow.” !2
Few of us ever have that luxury—hence the rise of refactoring, orevolving abad and/or limited
design into a good design—but we can all recognize the appeal of a second system. A second
system can avoid the mistakes of the first;a second system has cleaner, mere capable entities
than the first, because the designers could see how things were really used.
NET, with its all the best ideas eclecticism, isa shining example ofthis second system.
effect, and you'll find that lots of familiar concepts are slightly different under NET.
Reference Types vs. Value Types
Value typesare a bit cheaper than reference types
Although the terminology is new, and the concepts are slightly different, the distinction between
reference types and value typesis not new to Delphi programmers. In native code Delphi, objects
live on the heap, while records and primitive data types live either in registers, or on the stack,
or inside of larger data types. However, while .NET reference types are basically the same as
native code Delphi class types, NET value types differ from their native code Delphi cognates
in three key ways. First, in native code Delphi, primitive data types can’thave methods, the way
NET value types can. Second, in native code Delphi, you can allocate space for a ‘value type’
on the heap and then refer to it viaa pointer, which is not possible on NET. Third, native code
Delphi has nothing like boxing a value type into an object.
Arelerence type is a class type. An instance of a reference typeis an object on the heap
Reference types get thelr name from the fact thata reference type variable actually contains
only the address of the object on the heap—a reference to the actual object. As per Chapter 1
areference isa pointer that you can't do pointer arithmetic on: the only three operationsallowed
on a reference are setting it, to point to an objector to Nil (or null, in C#); dereferencing it, or
doing something with the object the reference points to; and comparing it to another reference
or Nil, or seeing whether or not two references are the same.
Value types are familiar, old-fashioned data types: characters, numbers, and records.
Numbers and characters are machine primitives, and records have been features of program-
ming languages for decades. .NET is more object oriented than Delphi, though, and even a
simple value like a character or a number can have methods. For example, instead of a loose
constellation offunctions like IntToStr or IntToHex, the various NET numeric types simply,
and consistently, override Object ToString.
As you can imagine, all that value type methods really mean at the object code level is that
flat procedures with explicit parameters have been turned into methods with implicit Self
(or this, in C#) parameters. At the same time, eliminating flat routines makes documentation
searches easier—instead of hunting for a funetion that takes a 32-bit integer parameter and
returns a string, you simply look at the methods that an Int32 supports.
12, Frederick Brooks, The Mythical Man Month, 1975
35a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL
Strings
Object-oriented, immutable, 16-bit Unicode
NET strings are very like an object-oriented version of native code Delphi strings. That is,
where native code Delphi strings are a fundamental data type that are treated specially by the
compiler, the NET String type descends directly from Object and is treated specially by the
CLR. (Every string is a String, not a String descendant. Strings are the only variable-length
objects the CLR supports.) Many of the flat string routines in the Delphi Systen and SysUtils
units correspond to methods or properties of the String class—and, in fact, on NET the Delphi
string type is a System.String (just as Tobject Is a Systen. Object), and many familiar Delphi
string routines are implemented on .NET as String method calls.
Tip You can continue to use the old, “portable” Delphi string routines in your Delphi for NET code—but
remember that learning the FCL is what will make you a .NET programmer” with access to more jobs.
cover String methods in Chapter 11, so this subsection just touches on the three major
differences between a Delphi AnsiString and NET’s String type.
First, there Is only one string type, and Ituses the 16-bit System. Char data type, which
contains Unicode characters in UTF-16 format. (Chapter 11 covers some of the issues that
Unicode strings raise with regard to reading and writing ASCII text files.) While most Unicode
characters fit into a 16-bit representation, notall do: justas on anative code system that uses a
MBCS (Multi-Byte Character Set) language, some Unicode code points! might actually take
two 16-bit characters. A string’s Length property is a count of the number of elementsin the
string’s Char array, which is not always the same as the number of Unicode code points. Simi-
larly, string indexing is hy Char, not by code point
Second, strings are not reference counted on .NET. This may seem obvious, but I think it
bears emphasizing, chiefly because of the way Delphi programmers use const parameters as a
optimization technique, to avoid reference count manipulation. There aren't any reference
counis on NET, and (except, perhaps, in portable code) you should use Delphi's const parameters
only for their semantics—that is, when you want the compiler to forbid you to change the
parameter's value.
Third, and most significant, NET strings are immutable. Once created, they cannot be
changed, and any methods that appear to change a string’s value actually create a new string,
Immutable strings have three benefits. The first benefit is that immutable strings eliminate
buffer overflow problems (where you change a string in place, but don’t notice that the now
string doesn’t fitin the space allocated for it), which are very common with C-style string libraries.
The second benefit is that immutable strings are inherently thread safe, as there is no way for
one thread to change a string while another thread is reading it. The third benefit is thatimmutable
strings prevent situations such as one method passing a string—by value—to another method,
15.A Unicode code point isa sort of abstract character—code point 32, for example, is the same
Unicode character whether it’s encoded as an 8-bit character (an ASCII space), a 16-bit character,
ora 32-bit character.
39a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.a
You have either reached a page that is unavailable for viewing or reached your viewing limit for this
book.CHAPTER 2 = THE OBJECT MODEL
In .NET L.x, delegates are always pointers to normal, named methods. Even when the
method is only asingle lineand/oris only called via a delegate, the delegate creation code must
refer to a separate method. In C# 2.0, you can create delegates as anonymous methods, which
are simply special blocks within a larger method. When the delegate is very short, this can make
your code much easier to read—you no longer have to jump around o see what your new
Thread (say) is doing, Additionally, snonymous methods can capture any parameters or in-scope
local variables, which can simplify calling sequences. See Chapter 8 for the details.
Finally, while you normally calla delegate exactly as ifit werea normal method, all delegates
support asynchronous execution. If the delegate has only a single method on its invocation list
(Le., U's nota multicast delegate), you can call Begininvoke (0 execute it in the background, on
a thread from the system ThreadPool (see Chapters @ and 17 for details). You can then do some
other work, andlater call End Invoke to release the background thread and collect the delegate’s
resull, ifany. Asynchronous execution can be a convenient alternative (o either creating &
thread or to explicitly manipulating the thread pool.
Caution When you use asynchronous execution, you must always pair a call o Beg In invoke witha call
to EndInvoke.
Namespaces
Hierarchical organization reduces naming conflicts
Namespaces area familiar concept if all the names ina program fall into a single pool, you're
very likely to have naming conflicts, especially when you use libraries from multiple vendors. By
allowing the creation of multiple, named pools of names, you greatly reduce the risk of naming,
conflicts, Namespaces also make it possible to resolve ambiguities when you do have name
conflicts. For example, you might have a Colors enum for both computer case colors and monitor
colors. With namespaces, you can refer to Case.Colors.Gray and Monitor.Colors.Black.!?
Delphi's unit syntaxis, in effect, a namespace scheme, but the NET namespace model is
abit more general than Delphi’s. The most obvious difference is that NET namespaces are
hierarchical—they can have dots in them. Less obviously, but equally importantly, NET
namespaces are not tied to source code files the way Delphi's are.
There are atleast two advantages to hierarchical namespaces. First, hierarchical namespaces
are “self-documenting” in much the same way that hierarchical method names are. For example,
the similarities and differences between Systen.Web.UL Design and Systen.Windows. Forms.
Design are quite clear. Similarly, hierarchical namespaces force related namespaces together
making it easier to find what you want. Systen.Windows .Forns and System.Windows. Forms.
Design are clearly related in a way that, say, WinForms and ConponentDesign would not be.
‘The second advantage to hierarchical namespaces is that they support a convention that
nonsystem namespaces should be rooted in a trademarked company name. Hypothetical
names like Microsoft .Sq1 Adapters and Borland.Sql.Adapters don’t conflict in the way that
17. This isan example of the .NET enum syntax, which { cover in the next subsection.