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

Csharp class design handbook
Nội dung xem thử
Mô tả chi tiết
C# Class Design Handbook: Coding Effective Classes
by Richard Conway et al. ISBN:1590592573
Apress © 2003
This text shows how to create robust, flexible, reusable classes with C# and learn how to understand
different types you can create in C#, as well as how classes relate to the .NET type framework.
Table of Contents
C# Class Design Handbook—Coding Effective Classes
Introduction
Chapter 1 - Defining Types
Chapter 2 - Type Members
Chapter 3 - Methods
Chapter 4 - Properties and Operators
Chapter 5 - Constructors and the Object Lifecycle
Chapter 6 - Events and Delegates
Chapter 7 - Inheritance and Polymorphism
Chapter 8 - Code Organization and Metadata
Appendix A - Support, Errata, and Code Download
Index
List of Figures
C# Class Design Handbook: Coding Effective Classes
by Richard Conway et al. ISBN:1590592573
Apress © 2003
This text shows how to create robust, flexible, reusable classes with C# and learn how to understand
different types you can create in C#, as well as how classes relate to the .NET type framework.
Table of Contents
C# Class Design Handbook—Coding Effective Classes
Introduction
Chapter 1 - Defining Types
Chapter 2 - Type Members
Chapter 3 - Methods
Chapter 4 - Properties and Operators
Chapter 5 - Constructors and the Object Lifecycle
Chapter 6 - Events and Delegates
Chapter 7 - Inheritance and Polymorphism
Chapter 8 - Code Organization and Metadata
Appendix A - Support, Errata, and Code Download
Index
List of Figures
Back Cover
The mission of the C# Class Design Handbook is to provide you with a critical understanding of designing classes,
making you better equipped to take full advantage of C#’s power to create robust, flexible, reusable classes. This
comprehensive guide lifts the lid on syntax and examines what’s really going on behind the scenes. Specific topics
include the role of types in .NET, the different kinds of types C# can create, the fundamental role of methods as
containers of program logic, and the workings behind .NET’s delegate-based event system. It will also show you how to
control and exploit inheritance in your types and how to create logical and physical code organization through
namespaces and assemblies.
Designing classes that don’t have to be revisited and revised over and over again is an art. This handbook aims to put
that art in your hands, giving you a deeper understanding of the decisions you must make to design classes, and
design them effectively.
About the Authors
Richard Conway started programming BASIC with the ZX81 at an early age, later graduating to using BASIC and 6502
assembly language, COMAL, and Pascal for the BBC B and Archimedes RISC machines. He is an independent software
consultant who lives and works in London. He has been using Microsoft technologies for many years and has
architected and built enterprise systems for IBM, Merrill Lynch, and Reuters. He has focused his development on
Windows DNA including various tools and languages, such as COM+, VB, XML, C++, J++, BizTalk and, more recently,
data warehousing. He has been actively involved in EAP trials with Microsoft for .NET My Services and the .NET
Compact Framework. His special area of interest is network security and cryptography.
Richard is a contributor to both C# Today and ASP Today, and he is currently involved in a product development and
consultancy alliance specializing in data warehousing and security products.
Teun Duynstee lives in the Netherlands and works with Macaw as a lead software developer.
Ben Hyrman works as a Program Architect for Best Buy in Minneapolis, Minnesota.
Roger Rowland is a freelance IT Consultant based in the UK. He has 25 years of software development experience on a
variety of platforms, and is a regular contributor to the Wrox C# Today web site. He currently specializes in Microsoft
technologies including VC++, VB, C#, SQL, and ASP. Roger is a member of the Institution of Analysts and
Programmers, a professional member of the British Computer Society, and a member of the IEEE Computer Society.
He holds a Masters Degree in computing and is currently undertaking a part-time PhD at the University of East Anglia
researching into medical imaging and computer assisted surgery. Research techniques include 3D graphics and volume
rendering using OpenGL, and he has published a number of academic papers.
James Speer has been a software developer since 1987, beginning his career in programming in BCPL and C++. He
currently specializes in distributed .NET component development, particularly – C#, .NET Remoting, Serviced
Components and MSMQ.
C# Class Design Handbook—Coding Effective Classes
Richard Conway
Teun Duynstee
Ben Hyrman
Roger Rowland
James Speer of Charteris plc
Apress™
Copyright © 2003 Apress
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.
(pbk):
1-59059-257-3
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.
Distributed to the book trade in the United States by Springer-Verlag New York, Inc., 175 Fifth Avenue, New
York, NY, 10010 and outside the United States by Springer-Verlag GmbH & Co. KG, Tiergartenstr. 17, 69112
Heidelberg, Germany.
In the United States: phone 1-800-SPRINGER, email [email protected], or visit http://www.springerny.com. Outside the United States: fax +49 6221 345229, email [email protected], or visit
http://www.springer.de.
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, email [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 Downloads section.
Some material first published in a different form in Visual Basic .NET Class Design Handbook (1-86100-708-
6), May 2002
Credits
Editorial Board
Dan Appleman
Craig Berry
Gary Cornell
Tony Davis
Steven Rycroft
Julian Skinner
Martin Streicher
Jim Sumser
Karen Watterson
Gavin Wright
John Zukowski
Additional Material
Damon Allison
Andy Olsen
Steven Sartain
Commissioning Editor
James Hart
Technical Editors
Fatema Beheranwala
Nilesh Parmar
Additional Editing
Andrew Polshaw
Technical Reviewers
Andrew Krowczyk
Roger Rowland
Managing Editor
Emma Batch
Index
Michael Brinkman
Project Manager
Beckie Stones
Production Coordinator
Sarah Hall
Proof Reader
Chris Smith
Cover
Natalie O'Donnell
About the Authors
Richard Conway
Richard Conway started programming BASIC with the ZX81 at an early age later graduating to using BASIC
and 6502 assembly language, COMAL, and Pascal for the BBC B and Archimedes RISC machines. He is an
independent software consultant who lives and works in London. He has been using Microsoft technologies
for many years and has architected and built enterprise systems for the likes of IBM, Merrill Lynch, and
Reuters. He has focused his development on Windows DNA including various tools and languages such as
COM+, VB, XML, C++, J++, BizTalk, and more recently, Data Warehousing. He has been actively involved in
EAP trials with Microsoft for .NET My Services and the .NET Compact Framework. He has spent the last two
and a half years since the release of the technical preview (of VS.NET) programming proof-of- concept and
enterprise system projects in C#. His special area of interest is Network Security and Cryptography. Richard is
a contributor to both C# Today and ASP Today. He is currently involved in a product development and
consultancy alliance – http://www.vertexion.co.uk – specializing in data warehousing and security products.
He can be contacted at
Teun Duynstee
Teun Duynstee lives in the Netherlands. He works with Macaw as a lead software developer and loves
programming, his girlfriend Marjolein, and Arnie the cat.
Ben Hyrman
Ben works as a Program Architect for Best Buy, in tropical Minneapolis, Minnesota. Ben enjoys the balmy
Minnesota weather with his loving wife, Dawn, and an overactive mutt of a dog, Bandit. When they're not busy
with work or off on road trips, Ben and Dawn enjoy painting their house and arguing over database design
patterns.
I would like to thank Damon Allison for being my sounding board for all of my crazy ideas. I'd also like to
thank Richard Scott, because he's British and he asked me to. Lastly, I'd like to thank Wrox for this
excellent opportunity.
Roger Rowland
Roger Rowland is a freelance IT Consultant based in the UK. He has 25 years of software development
experience on a variety of platforms, and is a regular contributor to the Wrox C# Today web site. He currently
specializes in Microsoft technologies including VC++, VB, C#, SQL, and ASP. Roger is a member of the
Institution of Analysts and Programmers, a professional member of the British Computer Society, and a
member of the IEEE Computer Society. He holds a Masters Degree in computing and is currently
undertaking a part-time PhD at the University of East Anglia researching into medical imaging and computer
assisted surgery. Research techniques include 3D graphics and volume rendering using OpenGL, and he has
published a number of academic papers. Married, with two children and always incredibly busy, Roger may
nevertheless be contacted at [email protected].
James Speer of Charteris plc
James has been a software developer since 1987, beginning his career programming in BCPL and C++. He
currently specializes in .NET component development, particularly - C#, .NET Remoting, Serviced
Components and MSMQ. James is currently employed by Charteris plc (http://www.charteris.com) as a
Senior Developer and can be reached at [email protected].
Thanks to Mom and Dad for the Acorn Electron and June for lending me your Vic 20.
C# Class Design Handbook
The book takes a top-down look at what exactly makes up a class in .NET. We begin by describing what a
type is, and how classes relate to the .NET type framework. Then we examine what makes up types: type
members. We devote the majority of the book to looking at the different mechanisms C# provides for defining
type members (methods, constructors, properties, operators, and events), and finally examine how types go
together to make up assemblies.
Introduction
C# is a language that follows in a grand tradition of programming language design; it draws its influences
from C++ and Java, and even Delphi and Visual Basic – a rich inheritance, which provides it with much that is
familiar to many developers, but also much that is alien or unexpected.
Programmers unfamiliar with object-oriented, C-family, ‘curly-bracket’ languages, perhaps coming to C# from
a background with Visual Basic 6 or ASP VBScript, often find the scope of the object-oriented features in C#
daunting. Those coming from other object-oriented platforms – C++ or Java for example – find some of C#'s
additional facilities surprising or confusing, while other, seemingly familiar syntaxes can behave in curiously
different ways.
This book takes the lid off C#'s object-oriented model, and examines how we use C# as a language for
creating classes (and, indeed, other kinds of types). Since everything we code in C# is a type, all our logic
belongs to methods of types, and the state of our program at any moment is tied up in the values stored in the
fields of instances of types in memory. A good understanding of how to create those types is therefore
fundamental to good C# programming.
We'll explore what options C# gives us in declaring types and type members in our code, and the impact our
decisions will have on code that uses our types. We'll see how we can code differently when our types are for
public use, and when types are for use within our own code. We'll look at what we can do to ensure our types
are only used in ways we design for, and how we can expose functionality from our types in a consistent,
logical, predictable, and user-friendly manner, for other code to exploit.
Who Is This Book For?
This book is for C# developers who want to explore the full capabilities of the .NET platform. If you want to
define your own data types, build your own class hierarchies, and build classes with robust interfaces, then
you need a deep understanding of the mechanisms C# provides for defining classes. That is the subject of
this book.
This book assumes you're already coding with C#, you're already familiar with the basic syntax, and you're
regularly writing code that works. You should be familiar with your chosen development tools and know how
to compile and run C# code.
You should be aware of .NET's basic object-orientation mechanisms – for example, that objects are
instances of classes, how objects are instantiated, and how methods and properties on an object are
accessed. We'll recap on the meaning and syntax of most of C#'s class construction keywords as we discuss
them, however.
What Does This Book Cover?
Every time we write code in C#, we're coding a class – it's unavoidable. This book addresses the decisions we
make as programmers in this environment, by placing them in the context of what they really are: decisions
about class design. So, when we write a method and choose whether to make it static, whether it is to be
public or private, what parameters it should take, and so on, this book helps us look at those decisions in
the context of how they impact on the design of a class.
This book takes a step back from the code we write every day and asks, "What is it really doing?" It asks you
not to consider each C# keyword or syntax construction just in terms of its effect, but to consider how it
accomplishes that effect. In the course of this book, we'll see how all our code is compiled into .NET types;
how we define type members; how type members are inherited; how types are aggregated into assemblies;
how we can control the creation of instances of types; and many more aspects of effective class coding.
What Doesn't It Cover?
This isn't a book about object-oriented analysis and design, UML modeling, or design patterns – although
we'll encounter all of these along the way, for detailed tutorials in these tools you should look elsewhere. It
doesn't address the question of how to take a business problem, and decide which classes you should code
to solve it. Instead, it focuses on the questions of implementation: how you can code a class that provides a
particular kind of behavior.
It also isn't a fundamental introduction to object-orientation, although any C# programmer should already be
familiar with the idea of having an instance of an object, and calling methods on it and accessing properties,
even if not with the process of defining your own types. If you're comfortable using objects, then this book will
not assume more than you know.
What Will You Learn?
The book takes a top-down look at what exactly makes up a class in .NET. We begin by describing what a
type is, and how classes relate to the .NET type framework. Then we examine what makes up types: type
members. We devote the majority of the book to looking at the different mechanisms C# provides for defining
type members (methods, constructors, properties, operators, and events), and finally examine how types go
together to make up assemblies.
Chapter by chapter, here's what to expect:
Chapter 1 – Defining Types
This chapter explains what exactly a type is, what role types play in .NET, and what kinds of types exist.
We also examine the different types we can declare in C# and how they map to .NET types.
Chapter 2 – Type Members
In the second chapter, we examine type members: what they are, how we can define them, and how we
can modify them using C# keywords. We also examine the type members inherited by every type from
the .NET root class, System.Object.
Chapter 3 – Methods
Methods are the workhorse of .NET applications; they contain all our program logic. This chapter
examines the behavior common to all methods, and how simple methods are defined in C#. We look at
how parameters are passed to methods, and how methods return values, or throw exceptions, to
communicate back to the code that called them.
Chapter 4 – Properties and Operators
Properties (both scalar and indexed) are a mechanism allowing us to create specialized methods for
accessing data belonging to our type. Operators are specialized methods that allow consumers of our
types to combine them using convenient operator-based syntax. This chapter examines how properties
are implemented, how indexed properties work, and the creation and use of operators.
Chapter 5 – Constructors and the Object Lifecycle
Constructors are special methods that are called to initialize new instances of a type. In this chapter, we
see how these special methods are coded, and how we can use them to control what code can create
instances of a type. We'll also examine object cloning, conversion operators, and some common coding
techniques for controlling the creation of instances of our classes.
Chapter 6 – Events and Delegates
The most complex type member in C# is the Event, and the most complex of C#'s types is the delegate.
Events are based on delegates, and the combination of the two can be quite daunting for programmers.
This chapter explains how delegates work, and then how .NET provides its event infrastructure through
delegate fields and specialized methods.
Chapter 7 – Inheritance and Polymorphism
A type is more than the sum of its members; it also has all the members it inherits from its superclass as
well. This chapter explains how .NET type inheritance works, when members are and aren't inherited,
and how we can control and exploit it using C#. We also look at the role and use of interfaces and
abstract classes.
Chapter 8 – Code Organization and Metadata
When we code a class in C#, we have to make some decisions about where exactly to put it, both
logically within a namespace structure, and physically, within a source file, and ultimately, within a .NET
assembly. This chapter discusses these issues. We also see how to add data to our classes that may be
of use to other code that makes use of them, using .NET metadata, and how to document our classes to
provide information for other programmers about how they are used.
What Do You Need?
To make use of this book, you need to be able to compile and execute code written in C#. This means you
will require either:
The .NET Framework SDK obtainable from Microsoft's MSDN site (http://msdn.microsoft.com), in the
Software Development Kits category. The download page at time of publication could be reached via the
following URL:
http://msdn.microsoft.com/downloads/sample.asp?
url=/msdn-files/027/000/976/msdncompositedoc.xml
A version of Visual Studio .NET that incorporates Visual C# .NET. The 2002 edition of the Visual C# .NET
IDE is included with the following Microsoft products:
Microsoft Visual C# .NET Standard
Microsoft Visual Studio .NET Enterprise Architect
Microsoft Visual Studio .NET Enterprise Developer
Microsoft Visual Studio .NET Professional
The product homepage is at http://msdn.microsoft.com/vstudio/.
There are several .NET implementations for other platforms underway, and support for C# compilation on
Linux, UNIX, and Windows is provided by the Mono project (http://www.go-mono.com/). Mono code does not
have access to the full Microsoft .NET class library, but follows the same syntactic rules as Microsoft's C#,
meaning the lessons in this book should apply in equal measure.
Chapter 1: Defining Types
Overview
C# is an object-oriented programming language, and one of the principles which guide its design is type
safety. During object-oriented analysis and design, we identify the most important objects in our system, and
consider how they will relate to each other. When we program in C#, classes are the main mechanism we
use to define the behavior of the objects that will exist in our program at run time. However, C# offers us a
great many ways to package up the code that defines our application – and not just in classes.
Whenever we code in C#, though, what we write are always types, and these types represent a combination
of behavior and data storage requirements. When the program runs, it creates instances of types (which
allocate the data storage required), and makes available the features of the types. Within the .NET
environment, type-safe code only accesses the memory locations it is authorized to access and types interact
only in well-defined, permitted ways. This is important for producing secure, stable applications that ensure
even badly written code can't do too much damage, and plays by the rules.
This book aims to help C# developers gain a deeper and more confident understanding of how to build well
designed classes that will behave correctly and consistently within the .NET Framework. Through exploration
and examples, we will give you an awareness of the consequences of decisions made during the design and
development phases, and will point out any not-so-obvious similarities with or differences from other objectoriented languages like C++ and Java.
We'll begin this book by looking at what exactly a type is. In this chapter, we'll examine .NET's type system,
and the kinds of type available to us as developers.
Types
In programming, we use the term ‘type’ to describe a particular kind of value. For example, C++ and Java
programmers will be familiar with types such as int, float, and double. For each type, the compiler
knows the following information:
How much memory to allocate when we create a value of this type
What operations are allowed to be performed using this value
The concept of types is fundamental to strongly typed programming languages, including all .NET languages.
In a strongly typed language, the type of value stored in each variable is known at compile time, so the
compiler can predict how we intend to use each variable, and can therefore tell us when we are going wrong.
A type is a contract. A variable of a particular type guarantees contractually that it will contain all the data you
would expect a value of the given type to have, and it can be processed in all the ways we would expect a
value of that type to be processed. We sometimes call the contract of a type its interface.
C++ Note: Having been used to defining the interfaces of your C++ classes in header files, you will
already be aware that C# has no header files. The definition of C# types is included in the
compiled assembly as metadata. You should also remember that the C# compiler does not
worry about the order of type declarations in your source code.
To a computer all data is just chains of ones and zeroes. When we have a variable in our program, ultimately
that variable is simply holding a binary number of some kind. So, when we ask the computer to display that
variable on the screen, perform a calculation on it, or retrieve one of the variable's properties, the computer
needs to know what type the variable contains in order to know how to interpret its value, and thus respond to
our request. For example, an integer and a single-precision floating-point number can both be stored in four
bytes of binary data. Take the following four bytes, for example:
00110110 11011011 10001010 01110100
If the value were interpreted as an integer, it would represent the number 920,357,492. Interpreted as a
single-precision floating-point value, it has the approximate value of 6.5428267E-6. So, if a variable contains
this binary number, and we ask .NET to add one to it, the result is going to depend not only on what value is in
the variable, but also on the variable type.
A type describes the purpose of any string of ones and zeroes in memory. It enables us to compare values of
two integers and see if one is greater than another, retrieve a string representing a value, or modify the value
in a particular way.
The .NET Type System
The .NET Framework includes a large selection of types that assists software development in the .NET
languages. All types we define and use in our own code must conform to the .NET Framework standards to
ensure that they operate correctly in the runtime environment. There are two important specifications that
define these standards, the Common Type System (CTS) and the Common Language Specification
(CLS).
The Common Type System (CTS)
The Common Type System shows compiler writers how to declare and use types used in the .NET runtime. It
defines rules that all .NET languages must follow in order to produce compiled code that can run within the
Common Language Runtime (CLR). The CTS provides an object-oriented framework within which individual
.NET languages operate. The existence of this common framework is crucial for ensuring type-safety and
security at run-time, and also facilitating cross-language integration. In essence, the Common Type System is
the backbone of the .NET Framework.
Figure 1 shows how the Common Type System is organized:
Figure 1
The diagram shows how the Common Type System makes a clear distinction between value types and
reference types, which are discussed below. It also allows us to define pure interfaces; an interface is a
simple definition of a contract, which is then implemented by another type (or types) – it separates out the
definition of a contract from the implementation of that contract. All of the other types combine the above two
things.
C++ Note: Interfaces are akin to pure abstract classes. Unlike in C++, a C# class may only inherit from
a single base class. However, a C# class may additionally inherit from multiple interfaces.
Java Note: Like Java, C# supports single inheritance of classes but multiple inheritance of interfaces.
Unlike Java-however, C# allows explicit implementation of interfaces, which avoids
problems with naming conflicts. We'll see this in action later.
The Common Language Specification (CLS)
While the CTS defines how types are created and managed within the runtime, the Common Language
Specification is more concerned with language interoperability. The CLS describes a minimum set of features
that must be supported by any compiler targeting the .NET runtime. While we're primarily C# developers, it is
important to understand the significance of .NET's language independence.
The CLS makes it extremely easy to use several different programming languages in the same application.
Whenever we compile source code written in a CLS-compliant language, it is compiled into a standard .NET
Framework byte code format called Microsoft Intermediate Language (MSIL). The CLS ensures that certain
types and language constructs are all compiled to the same MSIL equivalents whatever the language used.
This means we can easily mix-and-match C#, Visual Basic .NET, Managed Extensions for C++, Visual J#, or
JScript .NET within the same application, provided we only use CLS compliant types in any public interfaces
declared in our code. To ensure this, the C# compiler can be instructed to check the code and issue warnings
if we break any rules.