If you’ve picked up this book, you’re probably among the many programmers who have come to appreciate how powerful the Microsoft .NET Framework can be as a platform for development. But you’ve also learned that, as with any platform, .NET has quirks that can trip up even the savviest programmer. Have you been surprised by feature behavior in the .NET language or the .NET Framework—including the CLR and Framework Class Library—or in Visual Studio .NET? If you’ve worked with .NET for any length of time, I suspect you are nodding your head with a sigh of agreement. Experience teaches us what to do and what to avoid, but in programming, we commonly acquire our knowledge the hard way: by making costly, hard-to-debug and time-consuming mistakes. My goal in writing this book is to save my fellow developers from some of that pain, by sharing the experiences (and bad code) that brought the pitfalls of .NET to light for me, and showing you how to avoid them (and write code that works).
I started working with .NET when it was in pre-release Beta 2. The following years have been a lot of fun. However, there have been days (and nights) when things were not so obvious, when the code would behave, shall I say, strangely, given my expectations as an experienced developer.
The gotchas and guidelines presented in this book have come from three sources: First, the insights I have gained from developing .NET applications. Second, the questions raised by the hundreds of inquisitive software developers I’ve had the privilege of training. Third, the thought-provoking articles and discussions I have come across at symposiums, user-group meetings, the Internet, as well as the MSDN documentation itself.
What’s a GOTCHA? According to Merriam-Webster, gotcha is defined as follows:
"Main Entry: got:cha Pronunciation: 'gä-ch& Function: noun Etymology: alteration of got you : an unexpected usually disconcerting challenge, revelation, or catch."
For me, .NET gotchas are those things that pop up unexpectedly when you’re programming in .NET. Things that are buried, just waiting for you! It is as if the environment is there, aware of its own idiosyncrasies, watching you as you work, but unable (or unwilling) to warn you as you fall into one of its traps.
I’m not talking about those little annoying quirks in Visual Studio that make it misbehave occasionally, nor the transient flaws you see while working with the debugger or editor. In this book, I focus on the .NET Framework and language features that have consistently exhibited behavior that was not obvious to me. Why should you be interested in learning about these? Because knowing these little gotchas will help you avoid mistakes. You’ll develop applications more quickly. Some solutions will improve the performance of your applications. Others will help you stay clear of problems that will make your code incorrect. Yet others will help you with hidden problems such as proper garbage collection.
Most books on .NET start by assuming that the reader knows little about it. Those books are intended to bring readers up to speed with .NET or one of its associated languages. As more and more people learn to use any technology, a need arises not just to learn how use it, but how to use it well, and do things right. Because experience is our best teacher, it always takes a few years for books that address those needs to appear.
Consider my own case, some years ago. I had taken the time to learn the C# language and was a serious developer (or so I thought), working hard to put the features and facilities of the language to prudent use. One day in the early ’90s, I walked into my colleague’s office and found a book entitled C++ FAQs by Marshal Cline on her table. Picking it up, I asked “Why would anyone who knows C++ read a book that lists questions and answers?” She smiled. I flipped through a few pages, and before I knew it, I found I had been standing there for several minutes reading the book, page after page. She finally interrupted and said, “Why would anyone who knows C++ be reading that book for so long?” I found it to be invaluable and bought a copy for myself (and I still have that book and its next edition in my library!) Other great books that I have enjoyed reading are Effective C++ and More Effective C++ by Scott Meyers, Essential COM by Don Box et al., and Effective Jav a by Joshua Bloch.
Programming in .NET has entered a stage where a large number of developers have learnt how to program what was a brand new platform only a few years ago. The time has arrived for books that teach good practices. I hope this book will serve, like the classics on COM and C++ that have preceded it, to educate software developers on the dos and don’ts of programming the .NET platform.
This book is intended for the .NET programmer in the trenches. This includes both C# and VB.NET programmers. I assume that you are fairly familiar with .NET programming using either C# or VB.NET. I also assume that you are acquainted with the terms and vocabulary used by Microsoft in describing the .NET platform. In addition to programmers, project leads and senior programmers may find this book helpful in setting standards and guidelines for their development teams.
.NET Gotchas is organized into eight chapters, each focusing on a different area of interest in .NET. Each item has a name, title, and includes code examples, discussions, and guidelines “In a Nutshell.” The items are grouped into the area that I find to be the most appropriate. At the end of each item, related gotchas are referenced for your convenience. The examples are presented in both C# and VB.NET (clearly marked so you can easily identify these without having to examine the code). The code is labeled with the directory where you can find the example when you download the source code from the online resource. The output shown is from the C# code, unless the output from C# differs from the VB.NET output, as is the case in a few gotchas. Where they are different, both the C# output and the VB.NET output are shown and discussed.
The Common Language Runtime (CLR) and the .NET framework provide programmers with a high level of abstraction and ease of use. They pave the way for writing code, more or less consistently, in any of the different languages supported by .NET. However, there are aspects of both that are confusing, misleading, or prone to misuse. Also, certain features and choices can impact the behavior or performance of your code. In this chapter I focus on those issues.
The translation of your source code into Microsoft Intermediate Language (MSIL) is the job of the C# and VB.NET compilers. However, there are things that are “lost in the translation.” While .NET allows you to develop code in the language of your choice, there are things that certain compilers do not look out for. In this chapter I discuss issues that will surprise you in the area of program compilation and the use of Visual Studio for development. Also, you will learn about the inconsistencies between the different language compilers.
.NET languages support object-oriented development, while avoiding some of the perils of powerful (but treacherous) languages like C++. Unfortunately, the .NET languages have introduced features that lead to poor object-oriented practices. Furthermore, while your experience with other languages may lead you to expect that certain features will behave in familiar ways, with .NET you will learn that this is not always so.
The MSIL is the core language of .NET. Code written in different .NET supported languages is translated into MSIL. This provides you the ability to interoperate with code written in different languages in a powerful and useful way. You can use the .NET language of your choice—the one that you are most comfortable with. Your team can mix different languages in developing your system. While all this sounds terrific, are there any issues that will get in the way? In this chapter you will learn the issues that can affect your efforts to interoperate between .NET languages.
.NET provides automatic garbage collection. There is nothing we have to do or worry about in terms of object lifetime. Just sit back and relax, we’re told. Does that sound too good to be true? While garbage collection is automatic, it may not do its work on the schedule you might prefer. As long as you are dealing with only managed resources this is not a problem. However, the reality is that you must often contend with unmanaged resources, which the CLR won’t know how or when to clean up. In this chapter you will learn about the various issues related to garbage collection and how to write code that works correctly.
Inheritance and polymorphism are core features in object-oriented programming. Compared to other object-oriented languages, .NET has introduced keywords and facilities that are either new or different. While these were provided with good intent, some are misleading. Not understanding these features can affect the extensibility of your code and make it harder to derive from your classes. In this chapter you will learn what to avoid and how to use other features related to inheritance and polymorphism.
Creating a thread is easy; managing it is another story. How do you take care of thread safety? Should you create your own thread or use a thread from the thread pool? How are exceptions handled in multithreaded applications? What other issues do you need to think about when creating a .NET multithreaded application? This chapter will help you understand the fundamental issues that can make a difference between the success or failure of a multithreaded application.
If you have to work with legacy code, .NET and COM interoperability is of interest to you. The COM-Interop facilities provided in .NET make this task almost seamless, and putting it to use appears pretty simple. However, to use COM-Interop correctly, you need some forethought and planning. If you think using a COM component from .NET is simple, think again. You need to fully understand issues related to the apartment of the thread, the resource cleanup, and the layering of your application. How do you expose your .NET components for COM interoperability? Should you just turn on the Visual Studio settings to register the type library? What do you need to do to make this effective? In this chapter you will learn how to effectively interoperate between .NET and COM.
I developed the gotchas in this book through my explorations of .NET Framework 1.1 and the language versions, tools, and compilers that accompany it, all of which are available in any edition (beyond the Standard Edition) of Visual Studio 2003. You will need Visual Studio 2003 and .NET Framework 1.1 to run my examples. I have also tested each of the gotchas with .NET 2.0 Beta 1 (a.k.a. Whidbey) and have noted any changes in behavior. If you are using a later .NET 2.0 Beta, your experience may differ from mine, depending on the build version you are using. Comments on .NET 2.0 are based on Beta 1, which is subject to change. I think it is inappropriate to comment on the behavior of a product while it is in Beta 1, so I have not added any new gotchas spotted when working with .NET 2.0 Beta 1.
Occasionally, I compare the speed of execution of a code example with the speed of execution of an alternative way of implementing the same logic. The performance comparison is simply empirical and has been done on a Dell Latitude C640 with a 2 GHZ Pentium 4 processor, 512 MB of RAM, and a 40GB hard drive running Windows Server 2003 Standard Edition. In running these comparisons, I used Visual Studio .NET 2003 with .NET 1.1. Nothing else intensive was being executed while measuring the performance.
The following typographical conventions are used in this book:
- Plain text
Indicates menu titles, menu options, menu buttons, and keyboard accelerators (such as Alt and Ctrl).
Indicates new terms, URLs, email addresses, filenames, file extensions, pathnames, directories, and Unix utilities.
Indicates commands, options, switches, variables, attributes, keys, functions, types, classes, namespaces, methods, modules, properties, parameters, values, objects, events, event handlers, XML tags, HTML tags, macros, the contents of files, or the output from commands.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values.
Several code examples used in this book illustrate errors or problems, and are not intended to be used as-is. To remind readers of this, I have marked those “gotcha” code examples with a ✗ in the code heading. Usable, gotcha-free code is marked with a ✓.
I’ve also provided several bibliographic resources in the Appendix. When referring to these sources in the main text, I have bracketed the author names as a citation. See the Appendix for full bibliographic information.
This book is here to help you get your job done. In general, you may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: ".NET Gotchas by Venkat Subramaniam. Copyright 2005 O’Reilly Media, Inc., 0-596-00909-7.”
If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at firstname.lastname@example.org.
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, CA 95472 (800) 998-9938 (in the United States or Canada) (707) 829-0515 (international or local) (707) 829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at:
To comment or ask technical questions about this book, send email to:
For more information about our books, conferences, Resource Centers, and the O’Reilly Network, see our web site at:
When you see a Safari® Enabled icon on the cover of your favorite technology book, that means the book is available online through the O’Reilly Network Safari Bookshelf.
Safari offers a solution that’s better than e-books. It’s a virtual library that lets you easily search thousands of top tech books, cut and paste code samples, download chapters, and find quick answers when you need the most accurate, current information. Try it for free at http://safari.oreilly.com.
When I read single-authored books, I usually visualize the author talking to me. Since I started working on this book, that image has changed; I visualize not just the author, but a team. I realize now that a great deal of teamwork goes into it! Some bright people from France, California, Massachusetts, Tennessee, Texas, and Virginia contributed to this book.
I am amazed to see how things have progressed since the thought of writing this book got into my head one hot summer afternoon last year. I would first like to thank Bruce Tate and Michael Loukides for connecting the dots and putting me in touch with O’Reilly. Thanks to John Osborn of O’Reilly for his encouragement and spearheading the development of this book. I like his high expectations for quality and emphasis on coverage to meet the needs of Java and C++ programmers.
This book would have been hard to read and taken a lot more time to get out if not for the incredible effort of Ralph P. Davis as the development editor. Ralph is diligent, technical, so pleasant to work with, and has a great sense of humor. I am amazed at how he managed all the edits and versions without missing a beat at any time. Thanks Ralph. I was also very fortunate to have the expert opinions of Christophe Nassare as the technical editor. A number of gotchas and examples are better due to him. Merci beaucoup, Christophe.
Thanks to Anthony Mason for reviewing the book and offering to help in any way possible when he heard I was writing. Naresh Chaudhary was one of the early reviewers of the book. Naresh, thanks for the important role you played in making this a better book. Thanks to Chau Nguyen and John A. Fuqua for taking time from their very busy schedule and providing valuable input. Special thanks to Surendra Bhat for not only reviewing the book, but for recommending other good reviewers as well. I admire your quality. I consider Ted Neward a perfect example of a great software developer. I am very privileged to have had him as one of the early reviewers of this book. Thanks Ted!
I would like to express my special thanks to Brad Abrams, lead program manager of the CLR team at Microsoft, for being kind enough to spend and hour discussing the book with me at the end of a very long day. The comments he provided after reviewing parts of the book have been very valuable.
Thanks to my friend Siva Thiagarajan who gave me the wings to get into training and mentoring, and paved the way for me to experiment and learn. I would like to thank Jay Zimmerman for providing me an opportunity to speak at the No Fluff Just Stuff software symposium series, and for encouraging me to write. You are a good friend and mentor.
I’ve learnt a great deal from my students in the industry and at the University. I’d like to thank those who have taken my courses and asked those excellent questions to further their understanding and mine.
Most of what I do has been influenced by the hard work of my parents, Padmavathy and Ramamurthy. Thank you both. Thanks to Professor PSK (uncle P. S. Krishnamoorthy) for getting me excited about computers. You have had more far-reaching influence on others than you realize. Thanks to my dear aunt and uncle, Mythili and Balu, for shaping me.
None of this would’ve been possible but for the sacrifice of my family. Thanks to my sons, Karthik and Krupakar, for being so patient when I had to hide in the office several nights and weekends. I am blessed with incredible support and encouragement from my wife Kavitha. Thank you for your love without gotchas!