0% found this document useful (0 votes)
27 views

.NET 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.

Uploaded by

adecara543
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
27 views

.NET 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.

Uploaded by

adecara543
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 483
.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, [email protected], 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 eeee vi 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 Bibliography Contents 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 vii CONTENTS 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 BS PART 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. . 127 CONTENTS 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 - 169 CHAPTER 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 .. xt CONTENTS 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 .... 304 CHAPTER 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 24 CHAPTER 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 473 CONTENTS ‘APPENDIX 3 APPENDIX 4 APPENDIX 5 ONDE oi veieeeae Configuration Files Glossary ......... Bibliography art .. 479 2 485 489 Table 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 MFD vill 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. xix cs 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, California 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. 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. xxi 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. 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. 6 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 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. 19 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 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 a 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 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 35 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 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. 39 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 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.

You might also like