Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# and the NET Platform, Second Edition - Andrew Troelsen.pdf
Скачиваний:
67
Добавлен:
24.05.2014
Размер:
22.43 Mб
Скачать

The Second Pillar: C#'s Inheritance Support

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Now that you haveAprseenss ©various2003 (1200techniquespages)

that allow you to create a single well-encapsulated class, it is time t

your attention to building a family of related classes. As mentioned, inheritance is the aspect of OOP that facilit

This comprehensive text starts with a brief overview of the

code reuse. InheritanceC# languagecomesandin thentwo flavors:quickly classicalmoves to inheritancekey technical(theand"is-a" relationship) and the containment/delegationarchitecturalmodelissues(the "hasfor .NET-a" relationship)developers. . Let's begin by examining the classical "is-a" model.

When you establish "is-a" relationships between classes, you are building a dependency between types. The b

TableideaofbehindContentsclassical inheritance is that new classes may leverage (and extend) the functionality of other classe C#illustrate,and theassume.NET Platform,that youSecondwish toEditiondefine two additional classes to model salespeople and managers. The hiera

looks something like what you see in Figure 4-9.

Introduction

Part One - Introducing C# and the .NET Platform

Chapter

Chapter

Part

Chapter

 

Chapter

with C#

Chapter

Lifetime

Chapter

 

Chapter

and Events

Chapter

Techniques

Part Three - Programming with .NET Assemblies

Figure 4-9: The employee hierarchy

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

As illustrated in Figure 4-9, you can see that a SalesPerson "is-a" Employee (as is a Manager—at least in a per

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

world). In the classical inheritance model, base classes (such as Employee) are used to define general charac

Part Four - Leveraging the .NET Libraries

that are common to all descendents. Subclasses (such as SalesPerson and Manager) extend this general func

Chapter 12 - Object Serialization and the .NET Remoting Layer

while adding more specific behaviors to the class.

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

In C#, extending a class is accomplished using the colon operator on the class definition (:). Therefore, you can

Chapter 15 - Programming with Windows Forms Controls syntactically model these relationships as follows:

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

// Add two new subclasses to the Employees namespace.

Part Five - Web Applications and XML Web Services

namespace Employees

Chapter 18 - ASP.NET Web Pages and Web Controls

{

Chapter 19 - ASP.NET Web Applications

public class Manager : Employee

Chapter 20 - XML Web Services

{

Index // Managers need to know their number of stock options.

List of Figures private ulong numberOfOptions;

List of Tables public ulong NumbOpts

{

get { return numberOfOptions;} set { numberOfOptions = value; }

}

}

public class SalesPerson : Employee

{

// Salespeople need to know their number of sales.

private int numberOfSales; public int NumbSales

{

get { return numberOfSales;} set { numberOfSales = value; }

}

}

}

C# and the .NET Platform, Second Edition

 

by Andrew Troelsen

ISBN:1590590554

 

 

Apress © 2003 (1200 pages)

 

Notice how eachThissubclasscomprehensivehas extendedtext startsthe basewithclassa briefbehavioroverviewbyofaddingthe a custom property that operates on underlying privateC#pointlanguageof data.ndBecausethen quicklyyou havemovesestablishedto key t chnicalan "isand-a" relationship, SalesPerson and Manage

architectural issues for .NET developers.

automatically inherited all public (and protected) members of the Employee base class. To illustrate:

// Create a subclass and access base class functionality.

Table of Contents

public static int Main(string[] args)

C# and the .NET Platform, Second Edition

{

Introduction

// Make a salesperson.

Part One - Introducing C# and the .NET Platform

SalesPerson stan = new SalesPerson();

Chapter 1 - The Philosophy of .NET

// These members are inherited from the Employee base class.

Chapter 2 - Building C# Applications stan.EmpID = 100;

Part Two - The C# Programming Language

stan.SetFullName("Stan the Man");

Chapter 3 - C# Language Fundamentals

// This is defined by the SalesPerson subclass.

Chapter 4 - Object-Oriented Programming with C# stan.NumbSales = 42;

Chapter 5 - Exceptions and Object Lifetime return 0;

Chapter 6 - Interfaces and Collections

}

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Needless to say, a child class cannot directly access private members defined by its parent class (as inheritanc

Part Three - Programming with .NET Assemblies

preserves encapsulation). Also, when the object user creates an instance of a subclass, encapsulation of privat

Chapter 9 - Understanding .NET Assemblies

is ensured:

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part// FourError!- Leveragi! Instanceg he .NETofLibrarieschild class cannot allow access to a base class' private

SalesPerson stan = new SalesPerson();

Ch pt r 12 - Object Serialization and the .NET Remoting Layer

stan.currPay; // <= error!

Chapter 13 - Building a Better Window (Introducing Windows Forms) Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

ChapterControlling16 - The SystemBase.IO NameClasspaceCreation

Chapter 17 - Data Access with ADO.NET

Currently, SalesPerson and Manager can only be created using a default constructor. With this in mind, assum

Part Five - Web Applications and XML Web Services

have added the following new five-argument constructor to the Manager type:

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter// Create20 - XMLa WebsubclassServicesusing a custom constructor.

Manager chucky = new Manager("Chucky", 92, 100000, "333-23-2322", 9000);

Index

List of Figures

List of Tables

If you look at the argument list, you can clearly see that most of these parameters should be stored in the mem variables defined by the Employee base class. To do so, you could implement this new constructor as follows:

//If you do not say otherwise, a subclass constructor automatically calls the

//default constructor of its base class.

public Manager(string fullName, int empID,

float currPay, string ssn, ulong numbOfOpts)

{

// This point of data belongs with us!

numberOfOptions = numbOfOpts;

//Leverage the various members inherited from Employee

//to assign the state data.

EmpID = empID;

SetFullName(fullName);

SSN = ssn;

 

C# and the .NET Platform, Second Edition

 

 

Pay = currPay;

ISBN:1590590554

}

by Andrew Troelsen

Apress © 2003 (1200 pages)

 

 

 

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

Although this is technically permissible, it is not optimal. First, like C++ and Java, unless you say otherwise, the constructor of a base class is called automatically before the logic of the custom Manager constructor is execu

After this point, the current implementation accesses four public members of the Employee base class to estab

Table of Contents

state. Thus, you have really made six hits (four inherited members and two constructor calls) during the creatio

C# and the .NET Platform, Second Edition derived object!

Introduction

PartTo helpOne -optimizeIntroducingthe creationC# nd theof a.NETderivedPlatformclass, you will do well to implement your subclass constructors to ex

Chcallpteran1appropriate- The Philosophycustomofbase.NETclass constructor, rather than the default. In this way, you are able to reduce th Chapternumber2of-callsBuildingto inheritedC# Applicationsinitialization members (which saves time). Let's retrofit the custom constructor to do

PartveryTwothing:- The C# Programming Language

Chapter 3 - C# Language Fundamentals

Chapter// This4 -time,Obj ct-Orienteduse theProgrammingC# 'base'withkeywordC# to call a custom

Chapter// constructor5 - Ex eptionsonandtheObjectbaseLifetimeclass.

Chapterpublic6 Manager(string- I terfaces and CollectionsfullName, int empID, float currPay,

string ssn, ulong numbOfOpts)

Chapter 7 - Callback In erfaces, Delegates, and Events

: base(fullName, empID, currPay, ssn)

Chapter 8 - Advanced C# Type Construction Techniques

{ numberOfOptions = numbOfOpts; }

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Here, your constructor has been adorned with an odd bit of syntax. Directly after the closing parenthesis of the

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

constructor's argument list there is a single colon followed by the C# "base" keyword. In this situation, you are e

Part Four - Leveraging the .NET Libraries

calling the four-argument constructor defined by Employee and saving yourself unnecessary calls during the cr

Chapter 12 - Object Serialization and the .NET Remoting Layer

of the child class. The SalesPerson constructor looks almost identical:

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

// As a general rule, all subclasses should explicitly call an appropriate

Chapter 15 - Programming with Windows Forms Controls

// base class constructor.

Chapter 16 - The System.IO Namespace

public SalesPerson(string fullName, int empID,

Chapter 17 - Data Access with ADO.NET

float currPay, string ssn, int numbOfSales)

Part Five - Web Applications and XML Web Services

: base(fullName, empID, currPay, ssn)

Chapter 18 - ASP.NET Web Pages and Web Controls

{ numberOfSales = numbOfSales; }

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Also be aware that you may use the "base" keyword any time a subclass wishes to access a public or protected

Index

member defined by a parent class. Use of this keyword is not limited to constructor logic. You will see example

List of Figures

the "base" keyword in this manner during our examination of polymorphism.

List of Tables

Regarding Multiple Base Classes

Speaking of base classes, it is important to keep in mind that C# demands that a given class have exactly one base class. Therefore, it is not possible to have a single type with two or more base classes (this technique is k multiple inheritance, or simply MI). As you will see in Chapter 6, C# does allow a given type to implement any n of discrete interfaces. In this way, a C# class can exhibit a number of behaviors while avoiding the problems ass with classic MI. On a related note, it is permissible to configure a single interface to derive from multiple interfac

(again, more details to come in Chapter 6).

Keeping FamilyC# and Secrets:the .NET Platform,The "protected"Second Edi ion Keyword

by Andrew Troelsen

ISBN:1590590554

As you already know, public items are directly accessible from any subclass, while private items cannot be

Apress © 2003 (1200 pages)

accessed from any object beyond the object that has indeed defined the private data point. C# takes the lead

This comprehensive text starts with a brief overview of the

of many other modernC# languageday objectand languagesthen quicklyandmovesprovidesto keyantechnicaladditionalandlevel of accessibility: protected.

architectural issues for .NET developers.

When a base class defines protected data or protected methods, it is able to create a set of members that can be accessed directly by any descendent. If you wish to allow the SalesPerson and Manager child classes

Tableto directlyof Contentsaccess the data sector defined by Employee, you can update the original Employee class definition

C#asandfollows:the .NET Platform, Second Edition

Introduction

Part// OneProtected- IntroducingstateC# anddatathe.NET Platform

Chapterpublic1 class- The PhilosophyEmployeeof .NET

Chapter{ 2 - Building C# Applications

Part Two//- TChilde C# Programmingclasses canLanguagedirectly access this information. Object users cannot.

Chapterprotected3 - C# LanguagestringFundamentfullName;ls

protected int empID;

Chapter 4 - Obj -Oriented Programming with C#

protected float currPay;

Chapter 5 - Exceptions and Object Lifetime

protected string empSSN;

Chapter 6 - Interfaces and Collections

...

Chapter 7 - Callback Interfaces, Delegates, and Events

}

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

The benefit of defining protected members in a base class is that derived types no longer have to access the

Chapter 10 - Processes, AppDomains, Contexts, and Threads

data using public methods or properties. The possible downfall, of course, is that when a derived type has

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

direct access to its parent's internal data, it is very possible to accidentally break existing business rules (such

Part Four - Leveraging the .NET Libraries

as the mini-novel that exceeds the page count). To be sure, when you define protected members, you are

Chapter 12 - Object Serialization and the .NET Remoting Layer

creating a level of trust between the parent and child class, as the compiler will not catch any violation of your

Chaptertype's business13 - Buildingrulesa. Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Finally, understand that as far as the object user is concerned, protected data is regarded as private (as the

Chapter 15 - Programming with Windows Forms Controls

user is "outside" of the family). Therefore, the following is illegal:

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

// Error! Can't access protected data from object instance.

Part Five - Web Applications and XML Web Services

Employee emp = new Employee();

Chapter 18 - ASP.NET Web Pages and Web Controls

emp.empSSN = "111-11-1111";

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

ListPreventingof Figures Inheritance: Sealed Classes

List of Tables

Classical inheritance is a wonderful thing. When you establish base class/subclass relationships, you are able to leverage the behavior of existing types. However, what if you wish to define a class that cannot (for whatever reason) be subclassed? For example, assume you have added yet another class to your employee namespaces that extends the existing SalesPerson type. Figure 4-10 shows the current update.

Figure 4-10: The extended employee hierarchy

PTSalesPerson isC#a classand therepresenting.NET Platform,(of course)Seconda partEdition-time salesperson. For the sake of argument, let's say that you wishbytoAensuredrew thatTroelsenno other developer is able to subclassISBN:1590590554from PTSalesPerson (after all, how much more part-timeApr sscan© 2003you(1200get thanpages)"part-time"?). To prevent others from extending a class, make use of the C# "sealed" keyword:This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

// Ensure that PTSalesPerson cannot act as a base class to others. publicsealed class PTSalesPerson : SalesPerson

{

Table of Contents

public PTSalesPerson(string fullName, int empID,

C# and the .NET Platform, Second Edition

float currPay, string ssn, int numbOfSales)

Introduction

: base(fullName, empID, currPay, ssn, numbOfSales)

Part One - Introducing C# and the .NET Platform

{

Chapter 1 - The Philosophy of .NET

// Interesting constructor logic...

Chapter 2 - Building C# Applications

}

Part Two - The C# Programming Language

// Other interesting members...

Chapter 3 - C# Language Fundamentals

}

Chapter 4 - Object-Oriented Programming with C# Chapter 5 - Exceptions and Object Lifetime

ChapterBecause6 PTSalesPersonInterfac andisCollectionssealed, it cannot serve as a base class to any other type. Thus, if you attempted

Chapterto extend7 PTSalesPerson,- Callback Interfaces,you receiveDel gates,compilerand Eventserror:

Chapter 8 - Advanced C# Type Construction Techniques

Part// ThreeCompiler- Programmingerror!withPTSalesPerson.NET Assembliesis sealed and cannot be extended!

Chapterpublic9 class- UnderstandingReallyPTSalesPerson.NET Assemblies : PTSalesPerson

Chapter{ ...10} - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

By and large, the "sealed" keyword is most useful when creating standalone utility classes. As an example,

Chapter 12 - Object Serialization and the .NET Remoting Layer

the String class defined in the System namespace has been explicitly sealed (also note that the String type

Chapter 13 - Building a Better Window (Introducing Windows Forms)

implements a set of interfaces that will be examined later in this text ... so feel free to ignore this for the time

Chapter 14 - A Better Painting Framework (GDI+) being):

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

publicsealed class string : object,

Chapter 17 - Data Access with ADO.NET

IComparable, ICloneable,

Part Five - Web Applications and XML Web Services

IConvertible, IEnumerable {...}

Chapter 18 - ASP.NET Web Pages and Web Controls Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Therefore, you cannot create some new class deriving from System.String:

Index

List of Figures

// Another error!

List of Tables

public class MyBetterString : string

{...}

Simply put, if you wish to build a class that leverages the functionality of a sealed class, your only option is to forego classical inheritance and make use of the containment/delegation model. (Speaking of which . . .)

Programming for Containment/Delegation

As noted a bit earlier in this chapter, inheritance comes in two flavors. We have just explored the classical "is- a" relationship. To conclude the exploration of the second pillar of OOP, let's examine the "has-a" relationship (also known as the containment/delegation model). Leaving behind the employee hierarchy for the time being, assume you have created a simple C# class modeling a radio:

// This type will function as a contained class.

public class Radio

{

C# and the .NET Platform, Second Edition public void TurnOn(bool on)

{

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

 

 

if(on)

 

 

This comprehensive ext starts with a brief overview of the

 

Console.WriteLine("Jamming...");

 

C# language and then quickly moves to key technical and

 

else

 

 

architectural issues for .NET developers.

");

 

Console.WriteLine("Quiet time

}

}

Table of Contents

C# and the .NET Platform, Second Edition

Introduction

Now assume you are interested in modeling an automobile. The Car class maintains a set of state data (the

Part One - Introducing C# and the .NET Platform

car's pet name, current speed, and maximum speed), all of which may be set using a custom constructor.

Chapter 1 - The Philosophy of .NET

Also, the Car type has a Boolean member variable (carIsDead) that represents the state of the automobile's

Chapter 2 - Building C# Applicatdefinition:ns

engine. Here is the initial

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

// This class will function as the containing class.

Chapter 4 - Object-Oriented Programming with C# public class Car

Chapter 5 - Exceptions and Object Lifetime

{

Chapter 6 - Interfaces and Collections

private int currSpeed;

Chapter 7 - Callback Interfaces, Delegates, and Events

private int maxSpeed;

Chapterprivate8 - AdvancedstringC# TypepetName;Construction Techniques

Part Threebool- ProgcarIsDeadamming with= false;.NET Assemblies

Chapterpublic9 - UnderstandingCar() .NET Assemblies

Chapter{10maxSpeed- Processes,= AppDomains,100;} Contexts, and Threads

public Car(string name, int max, int curr)

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based P ogramming

{

Part Four - Leveraging the .NET Libraries

currSpeed = curr;

Chapter 12 - Object Serialization and the .NET Remoting Layer

maxSpeed = max;

Chapter 13 - Building a Better Window (Introducing Windows Forms)

petName = name;

Chapter 14 - A Better Painting Framework (GDI+)

Chapter}15 - Programming with Windows Forms Controls

public void SpeedUp(int delta)

Chapter 16 - The System.IO Namespace

{

Chapter 17 - Data Access with ADO.NET

// If the car is already dead print error message...

Part Five - Web Applications and XML Web Services

if(carIsDead)

Chapter 18 - ASP.NET Web Pages and Web Controls

 

Console.WriteLine("{0} is out of order....", petName);

Chapter 19 - ASP.NET Web Applications

else

// Car is not currently maxed out, so speed up.

Chapter 20 - XML Web Services

{

 

Index

currSpeed += delta;

List of Figures

// Did we exceed the car's max speed?

 

List of Tables

if(currSpeed >= maxSpeed)

 

{

Console.WriteLine("Sorry, {0} has overheated...", petName); carIsDead = true;

}

else

Console.WriteLine("=> CurrSpeed = {0}", currSpeed);

}

}

}

At this point, you have two independent classes. Obviously, it would be rather odd to establish an "is-a" relationship between the two entities. However, it should be clear that some sort of relationship between the two could be established. In short, you would like to express the idea that the Car "has-a" Radio. In OO parlance, a class that wishes to contain another class is termed the containing class. The inner class is often

Part Two - The C# Programming Language
Chapter 2 - Building C# Applications
Chapter 1 - The Philosophy of .NET
Part One - Introducing C# and the .NET Platform

termed a contained class. To begin, you can update the Car class definition as follows:

 

C# and the .NET Platform, Second Edition

 

 

by Andrew Troelsen

ISBN:1590590554

// A Car has-Apressa Radio.© 2003 (1200 pages)

 

public class Car

 

{

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

...

architectural issues for .NET developers.

 

// The contained Radio. private Radio theMusicBox;

Table} of Contents

C# and the .NET Platform, Second Edition

Introduction

Notice how the outer Car class has declared the Radio object as private. This, of course, is typically a good thing, as you have preserved encapsulation. However, the next obvious question is: How can the outside world interact with contained objects? It should be clear that it is the responsibility of the outer Car class to create the contained Radio class. Although the containing class may create any child objects whenever it

sees fit, one common place to do so is in the type's constructor set:

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

// Containing classes are responsible for creating any child objects.

Chapter 5 - Exceptions and Object Lifetime public class Car

Chapter 6 - Interfaces and Collections

{

Chapter 7 - Callback Interfaces, Delegates, and Events

...

Chapter 8 - Advanced C# Type Construction Techniques private Radio theMusicBox;

Part Three - Programming with .NET Assemblies

public Car()

Chapter{9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

maxSpeed = 100;

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming theMusicBox = new Radio();

Part Four - Leveraging the .NET Libraries

}

Chapter 12 - Object Serialization and the .NET Remoting Layer public Car(string name, int max, int curr)

Chapter{13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 -currSpeedA Better Painting= curr;Framework (GDI+)

Chapter 15 -maxSpeedProgramming= withmax;Windows Forms Controls

petName = name;

Chapter 16 - The System.IO Namespace

theMusicBox = new Radio();

Chapter 17 - Data Access with ADO.NET

}

Part Five - Web Applications and XML Web Services

}

Chapter 18 - ASP.NET Web Pages and Web Controls Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Alternatively, rather than duplicate the same code in each custom constructor, you could make use of the C#

Index

initializer syntax (see Chapter 3) as follows:

List of Figures

List of Tables

// A Car has-a Radio.

public class Car

{

private Radio theMusicBox = new Radio();

...

}

At this point, you have successfully contained another object. However, to expose the functionality of the inner class to the outside world requires delegation. Delegation is simply the act of adding members to the containing class that make use of the contained classes' functionality. For example:

//Containing classes extend their public interface to provide access to

//the contained classes.

public class Car

{

...

C# and the .NET Platform, Second Edition

 

public void CrankTunes(bool state)

ISBN:1590590554

{

by Andrew Troelsen

Apress © 2003 (1200 pages)

 

 

// Delegate request to inner object.

 

This comprehensive text starts with a brief overview of the

 

theMusicBox.TurnOn(state);

 

}

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

 

}

Table of Contents

C# and the .NET Platform, Second Edition

In the following code, notice how the object user is able to interact with the hidden inner object indirectly, and

Introduction

is totally unaware of the fact that the Car class is making use of a private Radio instance:

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

// Take this car for a test drive.

Chapter 2 - Building C# Applications

public class CarApp

Part Two - The C# Programming Language

{

Chapter 3 - C# Language Fundamentals

public static int Main(string[] args)

Chapter{4 - Object-Oriented Programming with C#

Chapter 5

- Exceptions and Object Lifetime

 

// Make a car (which makes the radio).

Chapter 6

- Interfaces and Collections

 

Car c1;

Chapter 7

- Callback Interfaces, De egates, and Events

 

c1 = new Car("SlugBug", 100, 10);

Chapter 8

- Advanced C# Type Construction Techniques

 

// Jam some tunes (which makes use of the radio).

Part Three - Programmingc1.CrankTunes(true);with .NET Assemblies

Chapter 9 - Understanding// Speed up.NET(andAssemblieswatch engine die...)

Chapter 10 - Prfor(intcesses, AppDomains,= 0; Contexts,< 10; i++)and Threads

c1.SpeedUp(20);

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

// Shut down (which again makes use of the radio).

Part Four - Leveraging the .NET Libraries

Chapter 12

- Objectc1.CrankTunes(false);Serialization and the .NET Remoting Layer

Chapter 13

- Buildingreturna Better0; Window (Introducing Windows Forms)

Chapter}14

- A Better Painting Framework (GDI+)

Chapter}

15

- Programming with Windows Forms Controls

Chapter 16

- The System.IO Namespace

Chapter 17

- Data Access with ADO.NET

Figure 4-11 shows the output.

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter

Chapter

Index

List of

List of

Figure 4-11: The contained Radio in action

SOURCE The Containment project is included under the Chapter 4 subdirectory.

CODE

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

This comprehensive text starts with a brief overview of the C# language and then quickly moves to key technical and architectural issues for .NET developers.

Table of Contents

C# and the .NET Platform, Second Edition

Introduction

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Chapter 19 - ASP.NET Web Applications
Chapter 18 - ASP.NET Web Pages and Web Controls
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming
Chapter 10 - Processes, AppDomains, Contexts, and Threads

Nested TypeC#Definitionsand the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Before examining the final pillar of OOP (polymorphism), let's explore a programming technique termed

Apress © 2003 (1200 pages)

nested types. In C#, it is possible to define a type (enum, class, interface, struct, delegate) directly within

This comprehensive text starts with a brief overview of the

the scope of classC#. Whenlanguageyouandhavethendonequicklyso, themovnestedto keytypetechnicalis consideredand a member of the nesting class, and in the eyes ofarchitecturalthe runtimeissuescan beformanipulated.NET dev loperslike.any "normal" member (fields, properties, methods, events, etc.). The syntax used to nest a type is quite straightforward:

Table of Contents

// C# allows classes to nest others.

C# and the .NET Platform, Second Edition

publicclass MyClass

Introduction

{

Part One - Introducing C# and the .NET Platform

// Members of outer class.

Chapter 1 - The Philosophy of .NET

...

Chapter 2 - Building C# Applications

public class MyNestedClass

Part Two{- The C# Programming Language

Chapter 3

- C# Language Fundamentals

 

 

// Members of inner class.

Chapter 4

- Object-Oriented Programming with C#

 

 

...

Chapter 5

- Exceptions and Object Lifetime

Chapter}

}

 

6

- Interfaces and Collections

Chapter 7

- Callback Interfaces, Delegates, and Events

Chapter 8

- Advanced C# Type Construction Techniques

Although the syntax is clean, understanding why you might do this is not readily apparent. Typically, a

Part Three - Programming with .NET Assemblies

nested type is regarded only as a helper type of the nesting type, and is not intended for use by the outside

Chapter 9 - Understanding .NET Assemblies

world. This is slightly along the lines of the "has-a" relationship; however, in the case of nested types, you are in greater control of the inner type's visibility. In this light, nested types also help enforce encapsulation

services. In general, when you are attempting to model the fact that type B makes no sense outside of the

Part Four - Leveraging the .NET Libraries

context of type A, nested classes do the trick.

Chapter 12 - Object Serialization and the .NET Remoting Layer

ChapterNote13 Be- Buildingaware thatBetterwhenWindowyou read(Introducingover the .WindowsNET literatureForms)(including online help samples) you may

Chapter 14 find- A Betterthat nestedPaintingrelationshipsFrameworkare(GDI+)denoted in text using the dollar sign token ($). Thus, if you

Chapter 15 come- Programmingacross Carwith$Radio,WindowsyouFormsare ableControlsto interpret this as "the Radio class is nested within the Chapter 16 Car- TheclassSy .tem" As.IOyouNamespacewill see during your examination of Windows Forms, the pattern of nesting

types within other types is commonplace, so make a mental note of the $ token!

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

To illustrate how to nest types, let's redesign your current Car application by representing the Radio as a private nested type. By doing so, you are assuming the outside world does not need to directly create a

Radio. In other words, you are attempting to programmatically capture the idea that a Radio type makes

Chapter 20 - XML Web Services

no sense outside of the Car to which it belongs. Here is the update:

Index

List of Figures

// The Car is nesting the Radio. Everything else is as before.

List of Tables

public class Car

{

...

//A nested, private radio that

//cannot be created by the outside world. private class Radio

{

public void TurnOn(bool on)

{

if(on) Console.WriteLine("Jamming...");

else

Console.WriteLine("Quiet time...");

}

}

// The outer class can make instances of nested types.

 

private Radio theMusicBox = new Radio();

 

}

C# and the .NET Platform, Second Edition

 

by Andrew Troelsen

ISBN:1590590554

 

 

Apress © 2003 (1200 pages)

 

Notice that the CarThistypecomprehis ablensiveto createtext objectstarts withinstancesa briefofoverviewany nestedof theitem. Also notice that this class has been declaredC#alanguageprivate typeand. thenIn C#,quicklynestedmovestypestomaykeybet chnicdeclaredl andprivate as well as public. Recall,

architectural issues for .NET developers.

however, that classes that are directly within a namespace (e.g., nonnested types) cannot be defined as private. As far as the object user is concerned, the Car type works as before. Because of the private,

nested nature of the Radio, the following is now illegal:

Table of Contents

C# and the .NET Platform, Second Edition

// Can't do it outside the scope of the Car class!

Introduction

Radio r = new Radio();

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Chapter 2 - Building C# Applications

However, the caller is able to interact with the nested Radio type indirectly as follows:

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

Car c1= new Car("SlugBug", 100, 10);

Chapter 4 - Object-Oriented Programming with C#

// Jam some tunes.

Chapter 5 - Exceptions and Object Lifetime c1.CrankTunes(true);

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part ThreeSOURCE- ProgrammingThewithNested.NETprojectAssemblis includedes under the Chapter 4 subdirectory.

CODE

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

The Third Pillar:C# nd theC#'s.NETPolymorphicPlatform, Second EditionSupport

by Andrew Troelsen

ISBN:1590590554

Switching back to the employees hierarchy, let's now examine the final pillar of OOP: polymorphism. Assume

Apress © 2003 (1200 pages)

that the Employee base class now defines a method named GiveBonus() as follows:

This comprehensive text starts with a brief overview of the C# language and then quickly moves to key technical and

architectural issues for .NET developers.

// Employee defines a new method that gives a bonus to a given employee.

public class Employee

{

Table of Contents

...

C# and the .NET Platform, Second Edition

public void GiveBonus(float amount)

Introduction

{

Part One - Introducing C# and the .NET Platform

currPay += amount;

Chapter}1 - The Philosophy of .NET

Chapter 2 - Building C# Applications

}

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

ChapterBecause4 this- Objectmethod-Orientedhas beenProgrammingdefined aswithpublic,C# you can now give bonuses to sales-persons and managers

(seeFigure 4-12 for output):

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter// Give7 -eachCallbackchildInterfaclasses, Delegates,bonusand. Events

ChManagerpter 8 -chuckyAdvanced=C#newTypeManager("Chucky",Construction Te hniques92, 100000, "333-23-2322", 9000);

PartchuckyThree.-GiveBonusProgramming(300);with .NET Assemblies

chucky.DisplayStats();

Chapter 9 - Understanding .NET Assemblies

SalesPerson fran = new SalesPerson("Fran", 93, 3000, "932-32-3232", 31);

Chapter 10 - Processes, AppDomains, Contexts, and Threads

fran.GiveBonus(200);

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

fran.DisplayStats();

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter

Chapter

Chapter

Chapter

Part

Chapter

Chapter

Chapter

Index

List of

List ofFigureTables 4-12: The current employee hierarchy does not honor polymorphism.

The problem with the current design is that the inherited GiveBonus() method operates identically for each subclass. Ideally, the bonus of a salesperson should take into account the number of sales. Perhaps managers should gain additional stock options in conjunction with a monetary bump in salary. Given this, you are suddenly faced with an interesting question: "How can related objects respond differently to the same request?"

Polymorphism is the final pillar of OOP, and it provides a way for a subclass to redefine how it responds to a method defined by its base class. To retrofit your current design, you need to revisit the use of the C# "virtual" and "override" keywords. When a base class wishes to define a method that may be overridden by a subclass, it must specify the method as virtual:

public class Employee

{

// GiveBonus() has a default implementation, however

public override void GiveBonus(float amount)

// child classes are free to override this behavior.

C# and the .NET Platform, Second Edition

 

public virtual void GiveBonus(float amount)

by Andrew Troelsen

ISBN:1590590554

{ currPay += amount; }

 

...

Apress © 2003 (1200 pages)

 

}This comprehensive text starts with a brief overview of the C# language and then quickly moves to key technical and architectural issues for .NET developers.

If a subclass wishes to redefine a virtual method, it is required to reimplement the method in question using

the "override" keyword. For example:

Table of Contents

C# and the .NET Platform, Second Edition

public class SalesPerson : Employee

Introduction

{

Part One - Introducing C# and the .NET Platform

// A salesperson's bonus is influenced by the number of sales.

Chapter 1 - The Philosophy of .NET

public override void GiveBonus(float amount)

Chapter 2 - Building C# Applications

{

Part Two - The C# Programming Language

int salesBonus = 0;

Chapter 3 - C# Language Fundamentals

if(numberOfSales >= 0 && numberOfSales <= 100)

Chapter 4 - Object-Oriented Programming with C# salesBonus = 10;

Chapter 5 - Exceptions and Object Lifetime

else if(numberOfSales >= 101 && numberOfSales <= 200)

Chapter 6 - Interfaces and Collections

salesBonus = 15;

Chapter 7 - Caelselback Interfaces, Delegates, and Events

Chapter 8 - AdvancedsalesBonusC# Type Construction= 20; Techniques// Anything greater than 200.

Part Three - Programmbase.GiveBonusng with .NET(amountAssemblies* salesBonus);

Chapter}9 - Understanding .NET Assemblies

Chapter... 10 - Processes, AppDomains, Contexts, and Threads

}

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

public class Manager : Employee

Chapter 12 - Object Serialization and the .NET Remoting Layer

{

Chapter 13 - Building a Better Window (Introducing Windows Forms)

private Random r = new Random();

Chapter 14 - A Better Painting Framework (GDI+)

// Managers get some number of new stock options, in addition to raw cash.

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

{

Chapter 17 - Data Access with ADO.NET

// Increase salary.

Part Five - Web Applications and XML Web Services

base.GiveBonus(amount);

Chapter 18 - ASP.NET Web Pages and Web Controls

// And give some new stock options...

Chapter 19 - ASP.NET Web Applications

numberOfOptions += (ulong)r.Next(500);

Chapter 20 - XML Web Services

}

Index

...

List of Figures

}

List of Tables

Notice how each overridden method is free to leverage the default behavior using the "base" keyword. In this way, you have no need to completely reimplement the logic behind GiveBonus(), but can reuse (and extend) the default behavior of the parent class.

Also assume that Employee.DisplayStats() has been declared virtual, and has been overridden by each subclass to account for displaying the number of sales (for sales-people) and current stock options (for managers). Now that each subclass can interpret what these virtual methods means to itself, each object instance behaves as a more independent entity (see Figure 4-13 for output):

// A better bonus system!

Manager chucky = new Manager("Chucky", 92, 100000, "333-23-2322", 9000);

chucky.GiveBonus(300);

chucky.DisplayStats();

SalesPerson fran = new SalesPerson("Fran", 93, 3000, "932-32-3232", 31);

C# and the .NET Platform, Second Edition fran.GiveBonus(200);

by Andrew Troelsen

ISBN:1590590554

fran.DisplayStats();

 

Apress © 2003 (1200 pages)

 

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

.

Table

C# and

Part

Chapter

Chapter

Part

Chapter

 

Chapter

 

Chapter 5

- Exceptions and Object Lifeti e

Figure 4-13: A better bonus system (thanks to polymorphism)

Chapter 6

- Interfaces and Collections

ChapterExcellent!7 -AtCallbackthis pointInterfaces,you are notDelegates,only ableandtoEventsestablish "is-a" and "has-a" relationships among related

classes, but also have injected polymorphic activity into your employee hierarchy. As you may suspect,

Chapter 8 - Advanced C# Type Construction Techniques

however, the story of polymorphism goes beyond simply overriding virtual methods.

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

ChapterDefining10 - Processes,(and Understanding)AppDomains, Contexts, andAbstractThreads Classes

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Currently, the Employee base class has been designed to supply protected member variables for its

Part Four - Leveraging the .NET Libraries

descendents, as well as supply two virtual methods (GiveBonus() and DisplayStats()) that may be overridden

Chapter 12 - Object Serialization and the .NET Remoting Layer

by a given descendent. While this is all well and good, there is a rather odd byproduct of the current design:

Chapter 13 - Building a Better Window (Introducing Windows Forms)

You can directly create instances of the Employee base class:

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

// What exactly does this mean?

Chapter 16 - The System.IO Namespace

Employee X = new Employee();

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Now think this one through. The only real purpose of the Employee base class is to define default state data

Chapter 19 - ASP.NET Web Applications

and behaviors for any given subclass. In all likelihood, you did not intend anyone to create a direct instance of

Chapter 20 - XML Web Services

this class. The Employee type itself is too general of a concept. For example, if I were to walk up to you and

Index

say, "I'm an Employee!", I would bet your very first question to me would be,"What kind of employee are you?

List of Figures

" (a consultant, trainer, admin assistant, copy editor, White House aide, etc.).

List of Tables

Given that base classes tend to be rather nebulous entities, in this example, a far better design is to prevent the ability to directly create a new Employee instance. In C#, you can enforce this programmatically by using the "abstract" keyword:

// Update the Employee class as abstract to prevent direct instantiation.

abstract public class Employee

{ ...}

With this, if you now attempt to create an instance of the Employee class, you are issued a compile time

error:

// Error! Can't create an instance of an abstract class.

Employee X = new Employee();

C# and the .NET Platform, Second Edition

Enforcing Polymorphic Activity: Abstract Methods

by Andrew Troelsen ISBN:1590590554

Apress © 2003 (1200 pages)

Once a class has been defined as an abstract base class, it may define any number of abstract members

(which is analogousThistocomprehensivea C++ pure virtualtext startsfunction)with. Abstracta rief overviewmethodsof canthe be used whenever you wish to

C# language and then quickly moves to key technical and

define a method that does not supply a default implementation. By doing so, you enforce a polymorphic trait

architectural issues for .NET developers.

on each descendent, leaving them to contend with the task of providing the details behind your abstract methods.

Table of Contents

The first logical question you might have is: Why would I ever want to do this? To understand the role of

C# and the .NET Platform, Second Edition

abstract methods, let's return to the shapes hierarchy seen earlier in this chapter (Figure 4-14).

Introduction

Part One - Introducing C# and the .NET Platform

Chapter

Chapter

Part

Chapter

Chapter

C#

Chapter

Chapter

Chapter 7 - Callback Interfaces, Delegates, and Events

Figure 4-14: Our current shapes hierarchy

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

ChapterMuch like9 the- Understandingemployee hierarchy,.NET Assembliesyou should be able to tell that you don't want to allow the object user to

create an instance of Shape directly, as it is too abstract of a concept. To prevent the direct creation of the

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Shape type, update your code as follows:

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chnamespacept r 12 - ObjectShapesSerialization and the .NET Remoting Layer

Chapter{ 13 - Building a Better Window (Introducing Windows Forms)

public abstract class Shape

Chapter 14 - A Better Painting Framework (GDI+)

{

Chapter 15 - Programming with Windows Forms Controls

// Shapes can be assigned a friendly pet name.

Chapter 16 - The System.IO Namespace

protected string petName;

Chapter 17 - Data Access with ADO.NET

// Constructors.

Part Five - Web Applications and XML Web Services

Chapter 18

- ASP.NETpublicWebShape(){Pages and WebpetNameControls= "NoName"; }

Chapter 19

- ASP.NETpublicWebShape(stringApplications

s) {

petName = s;}

Chapter 20

- XML//WebDraw()Servicesis virtual and

may be overridden.

Index

public virtual void Draw()

 

{

 

 

List of Figures

Console.WriteLine("Shape.Draw()");

List of Tables }

public string PetName

{

get { return petName;} set { petName = value;}

}

}

// Circle does NOT override Draw().

public class Circle : Shape

{

public Circle() { }

public Circle(string name): base(name) { }

}

// Hexagon DOES override Draw().

public class Hexagon : Shape

{

C# and the .NET Platform, Second Edition public Hexagon(){ }

by Andrew Troelsen ISBN:1590590554 public Hexagon(string name): base(name) { }

Apress © 2003 (1200 pages)

public override void Draw()

{This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

Console.WriteLine("Drawing {0} the Hexagon", petName); architectural issues for .NET developers.

}

}

}

Table of Contents

C# and the .NET Platform, Second Edition

Introduction

Notice that the Shape class has defined a virtual method named Draw(). As you have just seen, subclasses

Part One - Introducing C# and the .NET Platform

are free to redefine the behavior of a virtual method using the "override" keyword (as in the case of the

Chapter 1 - The Philosophy of .NET

Hexagon class). The point of abstract methods becomes crystal clear when you understand that subclasses

Chapter 2 - Building C# Applications

are not required to override virtual methods (as in the case of Circle). Therefore, if you create an instance of ParttheTwoHexagon- TheandC# ProgrammingCircle types, Languageyou'd find that the Hexagon understands how to draw itself correctly. The ChapterCircle, 3however,- C# Languageis more thanFundamentalsbit confused (see Figure 4-15 for output):

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

// The Circle object did not override the base class implementation of Draw().

Chapter 6 - Interfaces and Collections

public static int Main(string[] args)

Chapter 7 - Callback Interfaces, Delegates, and Events

{

ChapterHexagon8 - Advancedhex C#= newType Hexagon("Beth");Construction T chniques

Part Thrhex-.PDraw();ogramming with .NET Assemblies

ChapterCircle9 - Understandicir = newg .NETCircle("Cindy");Assemblies

Chapter//10Humm- Processes,. UsingAppDomains,base classContexts,implementationand Thre ds .

cir.Draw();

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

...

Part Four - Leveraging the .NET Libraries

}

Chapter 12 - Object Serialization and the .NET Remoting Layer Chapter 13 - Building a Better Window (Introducing Windows Forms) Chapter 14 - A Better Painting Framework (GDI+)

Chapter

Chapter

Chapter

Part

Chapter

Chapter

ChapterFigure20 - 4XML-15:WebVirtualServicesmethods do not have to be overridden.

Index

Clearly this is not a very intelligent design. To enforce that each child object defines what Draw() means to

List of Figures

itself, you can simply establish Draw() as an abstract method of the Shape class, which by definition means

List of Tables

you provide no default implementation whatsoever (again, like a C++ pure virtual function). Note that abstract methods can only be defined in abstract classes. If you attempt to do otherwise, you will be issued a compiler error:

// Force all kids to figure out how to be rendered.

publicabstract class Shape

{

...

// Draw() is now completely abstract (note semicolon).

public abstract void Draw(); public string PetName

{

get { return petName;} set { petName = value;}

}

}

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

Given this, you areApressnow ©obligated2003 (1200topages)implement Draw() in your Circle class. If you do not, Circle is also

assumed to be aThisnoncreatableompreh nsiveabstracttexttypestartsthatwithmusta briefbe adornedove vi wwithof thethe "abstract" keyword (which is

obviously not veryC#usefullanguagein thisandexample):then quickly moves to key technical and architectural issues for .NET developers.

// If we did not implement the abstract Draw() method, Circle would also be

// considered abstract, and could not be directly created!

Table of Contents

public class Circle : Shape

C# and the .NET Platform, Second Edition

{

Introduction

public Circle(){ }

Part One - Introducing C# and the .NET Platform

public Circle(string name): base(name) { }

Chapter 1 - The Philosophy of .NET

// Now Circle must decide how to render itself.

Chapter 2 - Building C# Applications public override void Draw()

Part Two - The C# Programming Language

{

Chapter 3 - C# Language Fundamentals

Console.WriteLine("Drawing {0} the Circle", PetName);

Chapter}4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

}

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

With this update, you are now able to enforce some order in your shapes hierarchy. To illustrate the full story

Chapter 8 - Advanced C# Type Construction Techniques

of polymorphism, consider the following code:

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter// Create10 - Processes,an arrayAppDomains,of variousContexts,Shapesand Threads.

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

PartpublicFour - staticLeveragingintthe Main(string[].NET Libra ies args)

{

Chapter 12 - Object Serialization and the .NET Remoting Layer

// Array of shapes.

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Shape[] s = {new Hexagon(), new Circle(), new Hexagon("Mick"),

Chapter 14 - A Better Painting Framework (GDI+)

new Circle("Beth"), new Hexagon("Linda")};

Chapter 15 - Programming with Windows Forms Controls

// Loop over the array and ask each object to draw itself.

Chapter 16 - The System.IO Namespace

for(int i = 0; i < s.Length; i++)

Chapter 17 - Data Access with ADO.NET

s[i].Draw();

Part Five - Web Applications and XML Web Services

...

Chapter 18 - ASP.NET Web Pages and Web Controls

}

Chapter 19 - ASP.NET Web Applications Chapter 20 - XML Web Services

Index

ListFigureof Figures4-16 shows the output.

List of Tables

Figure 4-16: Better! Abstract members must be overridden.

This illustrates polymorphism at its finest. Recall that when you mark a class as abstract, you are unable to create a direct instance of that type. However, you can freely store references to any subclass within an abstract base variable. As you iterate over the array of Shape references, it is at runtime that the correct type is determined. At this point, the correct method is invoked.

Versioning Class Members

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

C# provides a facility that is the logical opposite of method overriding: method hiding. Assume you have

Apress © 2003 (1200 pages)

added a brand new class named Oval to the current shapes hierarchy. Given that an Oval "is-a" type of

This comprehensive text starts with a brief overview of the

Circle, you may wish to extend the shapes hierarchy as shown in Figure 4-17.

C# language and then quickly moves to key technical and architectural issues for .NET developers.

Table

C# and

Part

Chapter

Chapter

Part

Chapter

ChapterFigure4 - 4Object-17: Versioning-O iented Programmingthe Draw() methodwi C#

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Now, for the sake of this argument, assume that the Oval also defines a method named Draw(). This is good,

Chapter 7 - Callback Interfaces, Delegates, and Events

as you can ensure that this class behaves like any other class in the hierarchy. However, what if you wish to

Chapter 8 - Advanced C# Type Construction Techniques

prevent the Oval class from inheriting any previous drawing logic? Formally, this technique is termed

Part Three - Programming with .NET Assemblies

versioning a class. Syntactically, this can be accomplished using the "new" keyword on a method-by-method

Chapter 9 - Understanding .NET Assemblies basis. For example:

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

// This class extends Circle, but hides the inherited Draw() method.

Part Four - Leveraging the .NET Libraries

public class Oval : Circle

Chapter 12 - Object Serialization and the .NET Remoting Layer

{

Chapter 13 - Building a Better Window (Introducing Windows Forms) public Oval(){ base.PetName = "Joe";}

Chapter 14 - A Better Painting Framework (GDI+)

// Hide any Draw() implementation above me.

Chapter 15 - Programming with Windows Forms Controls public new void Draw()

Chapter 16 - The System.IO Namespace

{

Chapter 17 - Data Access with ADO.NET

// Oval specific drawing algorithm.

Part Five}- Web Applications and XML Web Services

Chapter} 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Because you used the "new" keyword in the definition of Draw(), you are guaranteed that if an object user

Index

makes an instance of the Oval class and calls Draw(), the most derived implementation is called. In effect,

List of Figures

the "new" method breaks the relationship between the abstract Draw() method defined by the base class and

List of Tables

the derived version:

// The Draw() defined by Oval will be called.

Oval o = new Oval();

o.Draw();

As an odd caveat, it is possible to trigger the base class implementation of a hidden method using an explicit cast (defined in the next section):

// The Draw() defined by Circle will be called!

Oval o = new Oval();

((Circle)o).Draw();

// Cast o to base class.

At this point, method hiding may seem to be little more than an interesting exercise in class design. However,

this technique can be very useful when you are extending types defined within another .NET assembly.

C# and the .NET Platform, Second Edition

 

Imagine that you have purchased a .NET *.dll from a third-party vendor, and wish to derive a new class from

by Andrew Troelsen

ISBN:1590590554

a base class in the third-party library. Now, what if the base type defines a Draw() method that is somehow

Apress © 2003 (1200 pages)

incompatible with your own Draw() method? To prevent object users from triggering a base class

This compr"newhensive text starts with a brief overview of the implementation, just use ."

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

Note You can also apply the new keyword of a field of a derived type to hide an identically named data type defined up the inheritance chain.

Table of Contents

SOURCE The shapes hierarchy can be found under the Chapter 4 subdirectory.

C# andCODEthe .NET Platform, Second Edition

Introduction

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Casting BetweenC# and theTypes.NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

At this point in the chapter, you have created a number of class hierarchies (employees, cars, and shapes). Ne

Apress © 2003 (1200 pages)

you need to examine the laws of casting between class types. First, recall the employee hierarchy. The topmos

This comprehensive text starts with a brief overview of the

member in your hierarchyC# languageis Systemand then.Objectqui kly. Givenmovesthetoterminologykey technicalofandclassical inheritance, everything "is-a" obj Furthermore, a partrch-timetecturalsalespersoni sues for"is.NET-a" salesperson,developers. and so forth. Therefore, the following implicit cast operations are legal:

Table of Contents

// A Manager 'is-a' object.

C# and the .NET Platform, Second Edition

object frank = new Manager("Frank Zappa", 9, 40000, "111-11-1111", 5);

Introduction

// A Manager 'is-a' Employee too.

Part One - Introducing C# and the .NET Platform

Employee moonUnit = new Manager("MoonUnit Zappa", 2, 20000, "101-11-1321", 1);

Chapter 1 - The Philosophy of .NET

// A PT salesperson 'is-a' salesperson.

Chapter 2 - Building C# Applications

SalesPerson jill = new PTSalesPerson("Jill", 834, 100000, "111-12-1119", 90);

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

ChapterThe first4 law- Objectof casting-Orientbetweend Programmingclass typeswithisC#that when two classes are related by an "is-a" relationship, it is

always safe to reference a derived class using a base class reference. This leads to some powerful programmi

Chapter 5 - Exceptions and Object Lifetime

constructs. For example, if you have a class named TheMachine that supports the following static function:

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapterpublic8 class- AdvancedTheMachineC# Type Construction Techniques

Part{ Three - Programming with .NET Assemblies

public static void FireThisPerson(Employee e)

Chapter 9 - Underst nd ng .NET Assemblies

Chapter {10

- Processes, AppDomains, Contexts, and Threads

 

Chapter 11

- Type// Reflection,Remove fromLate Binding,databaseand Attribute... -Based Programming

Part Four - Leveraging// Getthekey.NETandLibrariespencil sharpener from fired employee...

Chapter }12

- Object Serialization and the .NET Remoting Layer

 

Chapter}

13

- Building a Better Window (Introducing Windows Forms)

Chapter 14

- A Better Painting Framework (GDI+)

 

Chapter 15

- Programming with Windows Forms Controls

 

you can effectively pass any descendent from the Employee class into this method, given the "is-a" relationship

Chapter 16

- The System.IO Namespace

 

Chapter 17

- Data Access with ADO.NET

 

// Streamline the staff.

 

Part Five - Web Applications and XML Web Services

 

Chapter 18

- ASP.NET Web Pages and Web Controls

// Fire MoonUnit.

TheMachine.FireThisPerson(moonUnit);

Chapter 19

- ASP.NET Web Applications

// Fire Jill.

TheMachine.FireThisPerson(jill);

Chapter 20

- XML Web Services

 

Index

List of Figures

The following logic works as there is an implicit cast from the base class type (Employee) to the derived type.

List of Tables

However, what if you also wanted to fire Frank Zappa (currently held in a generic System.Object reference)? If pass the object reference into the TheMachine.FireThisPerson() method as follows:

// A Manager 'is-a' object, but...

object frank = new Manager("Frank Zappa", 9, 40000, "111-11-1111", 5);

...

TheMachine.FireThisPerson(frank);

// Error!

you are issued a compiler error! The reason for the error is because of the fact that you cannot automatically tr a base type reference (in this case System.Object) as a derived type (in this case Employee) without first performing an explicit cast.

In C#, explicit casts are denoted by placing parentheses around the type you wish to cast to, followed by the typ you are attempting to cast from. For example:

// Cast from the generic System.Object into a strongly

C# and the .NET Platform, Second Edition

// typed Manager.

by Andrew Troelsen

ISBN:1590590554

Manager mgr = (Manager)frank;

 

Apress © 2003 (1200 pages)

 

Console.WriteLine("Frank's options: {0}", mgr.NumbOpts);

This comprehensive text starts with a brief overview of the C# language and then quickly moves to key technical and

architectural issues for .NET developers.

If you would rather not declare a specific variable of "type to cast to", you are able to condense the previous co as follows:

Table of Contents

C#//andAnthe'inline'.NET Platform,explicitSecond Editioncast.

Console.WriteLine("Frank's options: {0}", ((Manager)frank).NumbOpts);

Introduction

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

As far as passing the System.Object reference into the FireThisPerson() method, the problem can be rectified

Chapter 2 - Building C# Applications follows:

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

// Better! Explicitly cast System.Object into an Employee.

Chapter 4 - Object-Oriented Programming with C#

TheMachine.FireThisPerson((Employee)frank);

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

ChapterDetermining8 - AdvancedtheC# Type"TypeConstructionof" EmployeeTechniques

Part Three - Programming with .NET Assemblies

Given that the static TheMachine.FireThisPerson() method has been designed to take any possible type derive

Chapter 9 - Understanding .NET Assemblies

from Employee, one question on your mind may be how this method can dynamically determine which derived

Chapter 10 - Processes, AppDomains, Contexts, and Threads

type was sent into the method. Furthermore, given that the incoming parameter is of type Employee, how can y

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

gain access to the specialized members of the SalesPerson and Manager types?

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

The C# language provides three ways to determine if a given base class reference is actually referring to a deri

Chapter 13

- Building a Better Window (I troducing Windo s Forms)

type: explicit casting (previously examined), the "is" keyword, and the "as" keyword. The "is" keyword is helpful i

Chapter 14

- A Better Painti g Framework (GDI+)

that it will return a Boolean that signals if the base class reference is compatible with a given derived type. To

illustrate how to make use of such techniques, ponder the following updated FireThisPerson() method:

Chapter 15

- Programming with Windows Forms Controls

Chapter 16

- The System.IO Namespace

Chapter 17 - Data Access with ADO.NET public class TheMachine

Part Five - Web Applications and XML Web Services

{

Chapter 18 - ASP.NET Web Pages and Web Controls

// Fire everyone >:-)

Chapter public19 - ASP.NETstaticWeb Applcationsvoid FireThisPerson(Employee e)

Chapter {20 - XML Web Services

Index

List of Figures

List of Tables

}

}

if(eis SalesPerson)

{

Console.WriteLine("Lost a sales person named {0}", e.GetFullName( Console.WriteLine("{0} made {1} sales...",

e.GetFullName(), ((SalesPerson)e).NumbSales);

}

if(eis Manager)

{

Console.WriteLine("Lost a suit named {0}", e.GetFullName()); Console.WriteLine("{0} had {1} stock options...",

e.GetFullName(), ((Manager)e).NumbOpts);

}

Here, you make use of the "is" keyword to dynamically determine the type of employee. To gain access to the NumbSales and NumbOpts properties, you make use of an explicit cast. As an alternative, you could make use the "as" keyword to obtain a reference to the more derived type (if the types are incompatible, the reference is s

to null):

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

SalesPerson pApress= e ©as2003SalesPerson;(1200 pages)

 

if(p != null)

 

This comprehensive text starts with a brief overview of the

Console.WriteLine("# of sales: {0}", p.NumbSales);

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

Note As you will see in Chapter 6, these same techniques (explicit cast, "is", and "as") can be used to obtai

Table of Contents

an interface reference from an implementing type.

C# and the .NET Platform, Second Edition

Introduction

PartNumericalOne - IntroducingCastsC# and the .NET Platform

Chapter 1 - The Philosophy of .NET

In addition to casting between objects, be aware that numerical conversions follow more or less the same rules

Chapter 2 - Building C# Applications

you are attempting to cast a "larger" numerical type to a "smaller" type (such as an integer to a byte), you must

Part Two - The C# Programming Language

also make an explicit cast that informs the compiler you are willing to accept any possible data loss:

Chapter 3

- C# Language Fundamentals

Chapter 4

- Object-Oriented Programming with C#

Chapterint x5= -30000;Exceptions and Object Lifetime

Chapterbyte b6

=- Interfaces(byte)x;and Collections // Loss of information here...

Chapter 7

- Callback Interfaces, Delegates, and Events

Chapter 8

- Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

However, when you are storing a "smaller" numerical type into a "larger" type (such as a byte to an integer), the

Chapter 9 - Understanding .NET Assemblies

type is implicitly cast on your behalf, as there is no loss of data:

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming byte b = 30;

Part Four - Leveraging the .NET Libraries

int x = b;

// No loss of information...

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

ChapterCool! This14 -concludesA Better Paintingour examinationFrameworkof(GDI+)how C# contends with the famed pillars of OOP. To close this chapter

Chapterallow me15to- Programmingpoint out fewithselectWindtoolsws Formsof VS .ControlsNET that aid in the construction of custom types.

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

GeneratingC#Classand theDefinitions.NET Platf rm, SecondUsingEditVisualon Studio .NET

by Andrew Troelsen

ISBN:1590590554

Over the course of this chapter, you have seen how the C# programming language contends with the

Apress © 2003 (1200 pages)

three pillars of OOP, by making use of the "Keyboard Wizard" (read: typing everything in by hand using a

This comprehensive text starts with a brief overview of the

text editor). WhileC#youlanguageare alwaysnd freethentoquicklydo thismovesvery thing,to keyittechnicalis worthandpointing out that Visual Studio .NET does provide a numberarchitecturalof integratedissues fortools.NETthatdeveallowpersyou. to build initial class definitions using various GUI input dialog boxes.

TableTo illustrateof Contentshow to leverage VS .NET, assume you have created a brand new console application (named C#whateverand theyou.NETchoosePlatform,-I calledSecondmineEditionClassWithWizards) and wish to insert a new class definition to the

project. Your first task is to select the Class View tab of the Solution Explorer window. From here, simply

Introduction

right-click the solution icon and select Add | Class (Figure 4-18).

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Chapter

Part

Chapter

Chapter

Chapter

Chapter

Chapter

Chapter

Part

Chapter

 

Chapter

 

Chapter

Based Programming

Part

 

Chapter

Layer

Figure 4-18: Adding a new class via VS .NET

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

The resulting dialog box will allow you to set up the initial class definition. As you can see from Figure 4-19,

Chapter 16 - The System.IO Namespace

the Class Options link of the wizard allows you to define whether the class is sealed or abstract, public or

Chapter 17 - Danyta Access with ADO.NET

internal, and optional XML code documentation (see Chapter 2).

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter

Chapter

Index

List of

List of

Figure 4-19: The Add Class Wizard

The Base Class link allows you to select the name of the new type's base class. Do note that the choice of base classes will depend on the set of classes defined in the currently selected namespace (Figure 4-20).

ISBN:1590590554

of the

and

Table

C# and

Part

Chapter

Chapter

Figure 4-20: Specifying the base class

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

Finally, the (rather poorly named) Inheritance link (Figure 4-21) allows you to choose the set of interfaces

Chapter 4 - Object-Oriented Programming with C#

(if any) the type will implement (not inherit).

Chapter 5 - Exceptions and Object Lifetime

Chapter 6 - Interfaces and Collections

Chapter

Chapter

Part

Chapter

Chapter

Chapter

Programming

Part

Chapter

Chapter

Chapter

Chapter

Chapter

Chapter

Part Five - Web Applications and XML Web Services

Figure 4-21: Implementing (not inheriting) select interfaces

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Once you have defined your new class using this integrated wizard, you will find your new type is now part

Chapter 20 - XML Web Services

of your current project and is a member of the current default namespace.

Index

List of Figures

ListAddingof Tables Members to Types Using Visual Studio .NET

VS .NET also supports the ability to add members to existing types using the Class View tab of the Solutions Explorer. To do so, simply right-click a type, and using the add menu, pick the member of your choice (field, property, method, or indexer, which will be defined in Chapter 8). Each possible option of the Add context menu will result in a unique dialog box. While I will assume you will check things out as you see fit, Figure 4-22 illustrates the result of electing to add a new method to an existing class. Do note that you are able to add any number of parameters to the member as well as configure a versioned, abstract, virtual, or static member. Of course, if your type is not defined as abstract, you cannot add an abstract member. Also, if your member is private, you cannot declare it using the "virtual" keyword.

ISBN:1590590554

of the

and

Table

C# and

Part

Chapter

Chapter

Figure 4-22: The Add Member Wizard

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

ChapterSo, at this4 -pointObjectyou-Orientedshould haveProgrammingsolid understandingwith C# of C#'s handling of the pillars of OOP (as well as

Chaptsomerinsights5 - Exceptionsas to howandVSObject.NET Lifetimecan aid in the process of defining custom types). The next chapter will

Chapterbuild upon6 -thisInterfacesfoundationand Collby examiningctions how to handle runtime anomalies using structured exception

Chandlingpter 7 and- CallbackshowingInterfaces,how the CLRDelegates,managesand Eventsan object's lifetime.

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter 13 - Building a Better Window (Introducing Windows Forms)

Chapter 14 - A Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

Index

List of Figures

List of Tables

Соседние файлы в предмете Программирование