Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

How to code .NET
Nội dung xem thử
Mô tả chi tiết
CYAN
MAGENTA
YELLOW
BLACK
PANTONE 123 CV
this print for content only—size & color not accurate 7" x 9-1/4" / CASEBOUND / MALLOY
(0.625 INCH BULK -- 232 pages -- 60# Thor)
THE EXPERT’S VOICE® IN .NET
Christian Gross
How to
Code .NET
Tips and Tricks for Coding .NET 1.1
and .NET 2.0 Applications Effectively
BOOKS FOR PROFESSIONALS BY PROFESSIONALS®
How to Code .NET: Tips and Tricks for Coding
.NET 1.1 and .NET 2.0 Applications Effectively
Dear Reader,
Like you, I am a coder, architect, and developer. People who are coders, architects, or developers strive to do their best, and if given the choice they will
always do something correctly. Of course, this begs the question: Why do we
have so many bugs in our code?
I think the main reason for buggy code is that we are all short on time. We
don’t have the luxury of investigating new Framework features fully or exploring
innovative new techniques as thoroughly as we would like, because we’re all
watching the clock. That means our code has bugs—the new Framework feature
we implemented doesn’t work quite as expected, and the new best practice we
put in place doesn’t seem to work the same way for every input. These bugs are
frustrating and can often be very difficult to solve.
This book is a response to that problem. In it I have investigated and recorded
my experiences of a wide range of .NET Framework features. They’re arranged
in simple, bite-sized sections dedicated to problem solving, informing you of
little-known functionality and keeping you up to date with the latest design
thinking. It’s a road map to your more effective use of the .NET Framework.
For example, the .NET Framework 2.0 introduced the yield keyword. On the
face of it, this is a really cool new piece of functionality that we’d all like to use.
But what’s it really like? Is it buggy? Is it going to be the future of all iterators?
This book digs into these questions and more to provide you with the answers
that you need.
Christian Gross
Author of
Ajax Patterns
and Best Practices
Ajax and REST Recipes: A
Problem-Solution Approach
Foundations of ObjectOriented Programming
Using .NET 2.0 Patterns
Shelve in
.NET
User level:
Beginner–Intermediate
How to Code .NET Gross
ISBN 1-59059-744-3
9 781590 597446
90000
6 89253 59744 6
Companion
eBook
Available
Companion eBook
See last page for details
on $10 eBook version
www.apress.com
SOURCE CODE ONLINE forums.apress.com
FOR PROFESSIONALS BY PROFESSIONALS™
Join online discussions:
Christian Gross
How to Code .NET
Tips and Tricks for Coding
.NET 1.1 and .NET 2.0
Applications Effectively
7443FM.qxd 9/21/06 10:46 PM Page i
How to Code .NET: Tips and Tricks for Coding .NET 1.1 and .NET 2.0 Applications Effectively
Copyright © 2006 by Christian Gross
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 (pbk): 978-1-59059-744-6
ISBN-10 (pbk): 1-59059-744-3
Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1
Trademarked names 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: Ewan Buckingham
Technical Reviewer: Jason Lefebvre
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: Richard Dal Porto
Copy Edit Manager: Nicole Flores
Copy Editors: Candace English, Nicole Abramowitz
Assistant Production Director: Kari Brooks-Copony
Production Editor: Kelly Gunther
Compositor: Gina Rexrode
Proofreader: Linda Seifert
Indexer: Michael Brinkman
Artist: April Milne
Cover Designer: Kurt Krames
Manufacturing Director: Tom Debolski
Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,
New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail [email protected], or
visit http://www.springeronline.com.
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 [email protected], or visit http://www.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 shall have any
liability to any person 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 http://www.apress.com in the Source Code/
Download section.
7443FM.qxd 9/21/06 10:46 PM Page ii
Contents at a Glance
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
■CHAPTER 1 Testing Your Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
■CHAPTER 2 .NET Runtime- and Framework-Related Solutions . . . . . . . 31
■CHAPTER 3 Text-Related Solutions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
■CHAPTER 4 C# Coding Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
iii
7443FM.qxd 9/21/06 10:46 PM Page iii
7443FM.qxd 9/21/06 10:46 PM Page iv
Contents
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
■CHAPTER 1 Testing Your Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Quick Notes About TDD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Getting Started with TDD and NUnit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Writing Tests Using Contexts and Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Writing Tests for Code Pieces That Have No Tests or Few Tests . . . . . . . . 11
Writing Tests for Code Pieces That Don’t Give Information Back . . . . . . . 19
Verifying the Correctness of an Object Instance
Without Having Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
■CHAPTER 2 .NET Runtime- and Framework-Related Solutions . . . . . . . 31
Keeping Value Types and Reference Types Straight . . . . . . . . . . . . . . . . . . 31
Using Delegates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Versioning Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Loading and Unloading Assemblies Dynamically. . . . . . . . . . . . . . . . . . . . . 47
Loading Assemblies Dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Loading and Unloading Assemblies Dynamically . . . . . . . . . . . . . . . . 52
Implementing GetHashCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Thinking of .NET Generics as Black Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Figuring Out What Generic Methods Do. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Using the new and class Keywords with .NET Generics. . . . . . . . . . . . . . . 82
■CHAPTER 3 Text-Related Solutions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Converting a String to an Array and Vice Versa . . . . . . . . . . . . . . . . . . . . . . 85
Parsing Numbers from Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Processing Plain-Vanilla Numbers in Different Cultures . . . . . . . . . . 89
Managing the Culture Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
v
7443FM.qxd 9/21/06 10:46 PM Page v
vi ■CONTENTS
When to Use StringBuilder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Finding a Piece of Text Within a Text Buffer . . . . . . . . . . . . . . . . . . . . . . . . 101
Always Implement ToString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Using a Disposable Type to Find Multiple Text
Pieces and Iterate the Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Making ToString Generate Structured Output. . . . . . . . . . . . . . . . . . . . . . . 110
■CHAPTER 4 C# Coding Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
What Does the Yield Keyword Really Generate? . . . . . . . . . . . . . . . . . . . . 117
Using Inheritance Effectively . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Implementing Interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Naming Conventions for a Namespace, a Class, and an Interface . . . . . 135
Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Class and Interface Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Understanding the Overloaded Return Type and Property . . . . . . . . . . . . 139
Nullable Types: A Null Is Not Always a Null . . . . . . . . . . . . . . . . . . . . . . . . . 145
Abstract-Class Bridge-Pattern Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Nested Private-Class Bridge-Pattern Variation. . . . . . . . . . . . . . . . . . . . . . 151
Dealing with Marker Interfaces or Base Classes . . . . . . . . . . . . . . . . . . . . 153
Editing Text Using the Command Pattern. . . . . . . . . . . . . . . . . . . . . . 154
Marker Interfaces and Their Dependencies . . . . . . . . . . . . . . . . . . . 156
How Marker Interfaces Dependencies Are Implemented . . . . . . . . 157
A Null Value Is Not Always a Null State . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
The Essentials of the Factory Pattern. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
The Classical Factory Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
More Sophisticated Factory Implementations . . . . . . . . . . . . . . . . . 173
Don’t Expose a Class’s Internal State. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Designing Consistent Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Immutable Types Are Scalable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Understanding and Using Functors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
The Comparer Functor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
The Closure Functor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
The Predicate Functor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
The Transformer Functor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Functors in Practice. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Avoiding Parameters That Have No Identity . . . . . . . . . . . . . . . . . . . . . . . . 205
■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
7443FM.qxd 9/21/06 10:46 PM Page vi
vii
Many people say that by looking at a person’s dog, you can tell what
the person is like. Well, the picture of me is my dog Louys, an English
Bulldog. And yes, my English Bulldog and I have many common
characteristics.
But what about my biography? It’s pretty simple: I am guy
who has spent oodles of time strapped to a chair debugging and
taking apart code. In fact, I really enjoy this business we call software development. I have
ever since I learned how to peek and poke my first bytes. I have written various books,
including Ajax and REST Recipes: A Problem-Solution Approach, Foundations of ObjectOriented Programming Using .NET 2.0 Patterns, and A Programmer’s Introduction to
Windows DNA, all available from Apress.
These days I enjoy coding and experimenting with .NET, as it is a fascinating environment. .NET makes me feel like a kid opening a present on Christmas morning. You had an idea
what the gift was, but you were not completely sure. And with .NET there is no relative giving
you socks or a sweater. It’s excitement all the way!
About the Author
7443FM.qxd 9/21/06 10:46 PM Page vii
7443FM.qxd 9/21/06 10:46 PM Page viii
About the Technical Reviewer
■JASON LEFEBVRE is vice president and founding partner of Intensity Software, Inc.
(http://www.intensitysoftware.com), which specializes in providing custom Microsoft .NET
applications, IT consulting services, legacy system migration, and boxed software products to
a rapidly growing set of clients. Jason has been using Microsoft .NET since its Alpha stages in
early 2000 and uses Visual Studio and the Microsoft .NET Framework daily while creating
solutions for Intensity Software’s clients. Jason has been a participating author for a number of
books and has written numerous articles about Microsoft .NET-related topics.
ix
7443FM.qxd 9/21/06 10:46 PM Page ix
7443FM.qxd 9/21/06 10:46 PM Page x
Acknowledgments
This book would not be complete without you, the reader. I came upon the idea for this
book after I realized that I had a number of “canned” solutions to problems that readers of my
articles, clients, or attendees of my conference sessions posed to me. For example, Andreas
Penzold, a reader of my materials, worked with me to figure out what you can expect of
GetHashCode and Equals.
xi
7443FM.qxd 9/21/06 10:46 PM Page xi
7443FM.qxd 9/21/06 10:46 PM Page xii
Introduction
The title of this book may seem odd; you probably already know how to write code in .NET.
But you can always benefit from knowing more. Coders, architects, and developers always
strive to do their best, and if given the choice to do something correctly or incorrectly they will
do it correctly. So why do we have so many bugs in our code? I could say, “Heck, it’s all the
managers making bonehead decisions.” It would be a popular answer, but it would not be
fair. We have bugs because humans and the communication between humans are imperfect.
The other major reason why code has bugs is that people do not have the time or energy
to pour resources into specific problems. When you are working on an application, you are
confronted with thousands of specific problems, and you have to assign a priority. This is
where this book is aimed. I take the time to investigate the specific problems and figure
out how to solve them. Your responsibility is to read the solutions and implement them as
appropriate.
This is not a patterns book, even though I reference patterns. It is not a book meant to solve
all problems, because like you I have to assign priority to the problems I want to solve. This book
is the first of a series, and subsequent volumes will solve more problems. This book aims to
look at a problem, feature, or fact and then figure out what that problem, feature, or fact implies.
As a quick example .NET 2.0 introduced the yield keyword. Cool use of technology, but
what does yield really imply? Is yield buggy? Is yield the future of all iterators? After reading
this book you’ll know all of yield’s implications and ramifications.
If you read this book and disagree with me, let me know why you disagree. Tell me what
you think I did wrong. Sometimes I will correct you, but other times, we’ll both learn something. Or if you want me to figure out a solution to a specific problem you are having, tell me.
If I end up writing about our discussion, I will credit you and give you a free copy of my next
book. Send your love or hate to [email protected].
Source Code
The source code is available in the Source Code/Download section of the Apress website
(http://www.apress.com). Additionally, you can visit http://www.devspace.com/codingdotnet
to download the code.
xiii
7443FM.qxd 9/21/06 10:46 PM Page xiii
7443FM.qxd 9/21/06 10:46 PM Page xiv