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

Summary C# and the .NET Platform, Second Edition

by Andrew Troelsen ISBN:1590590554

In this chapter, you have examined a number of ways in which multiple objects can partake in a

Apress © 2003 (1200 pages)

bidirectional conversation under .NET. First, you examined the use of callback interfaces, which provide a

This comprehensive text starts with a brief overview of the

way to have objectC#Blanguagemake callsandonthenobjectquicklyA viamovesan interfaceto key technicalreferenceand. Do understand that this design pattern is not specificarchitoectural.NET,issbutesmayfor .beNETemployeddevelopersin.any language or platform that honors the use of interface types.

TableNext,ofyouContentsexamined the C# "delegate" keyword, which is used to indirectly construct a class derived from C#Systemand the.MulticastDelegate.NET Platform, Second. As youEditionhave seen, a delegate is simply an object that maintains a list of

methods to call when told to do so. These invocations may be made synchronously (using the Invoke()

Introduction

method) or asynchronously (via the BeginInvoke() and EndInvoke() methods).

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

Finally, you examined the C# "event" keyword which, when used in conjunction with a delegate type, can simplify the process of sending your event notifications to awaiting callers. As seen via the resulting CIL,

the .NET event model maps to hidden calls on the System.Delegate/System.MulticastDelegate types. In

Chapter 3 - C# Language Fundamentals

this light, the C# "event" keyword is purely optional in that it simply saves you some typing time.

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 C#8:andAdvancedthe .NET Platform,C#SecondTypeEditionConstruction

by Andrew Troelsen

ISBN:1590590554

Techniques

 

Apre © 2003 (1200 pages)

 

This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

This chapter wraps up our investigation of the C# programming language by examining a number of

architectural issues for .NET developers.

advanced (but extremely useful) syntactic constructs. To begin, we will examine a small set of C# keywords that we have not yet formally examined. For example, you will learn how to programmatically

account for overflow/underflow conditions using the "checked"/"unchecked" keywords as well as how to

Table of Contents

create an "unsafe" code context in order to directly manipulate pointer types using C#.

C# and the .NET Platform, Second Edition

Introduction

Next, you learn how to construct and use an indexer method. This C# mechanism enables you to build PartcustomOne -typesIntroducingthat exposeC# andinternalthe .NETsubtypesPlatformusing the familiar bracket operator (i.e., []). If you have a C++ Chbackground,pter 1 - TheyouPhilosophywill find thatof .creatingNET a C# indexer method is analogous to overloading the [] operator on

Chaptera C++ class2 - .BuildingOnce youC# learnApplicationshow to build an indexer method, you then examine how to overload various

PartoperatorsTwo - The(+, –C#, <,Programming>, and so forth)Languageand create custom conversion functions (the C# equivalent to

Chapteroverloading3 - C#theLanguage() operatorFundamentalsunder C++) for a type.

Chapter 4 - Object-Oriented Programming with C#

ChaptTherAdvanced5 - Exceptions andKeywordsObject Lifetimeof C#

Chapter 6 - Interfaces and Collections

ChapterOver the7 course- Callbackof theIntepreviousfaces, Delegates,seven chapters,and Eventsyou have seen a majority of the C# keywords in action. In

addition to those already investigated, C# does have a set of lesser used, but still intriguing, keywords,

Chapter 8 - Advanced C# Type Construction T chniques

specifically

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

"checked"/"unchecked"

Chapter 10 - Processes, AppDomains, Contexts, and Threads

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

"unsafe"/"stackalloc"/"fixed"/"volatile"/"sizeof"

Part Four - Leveraging the .NET Libraries

"lock"

Chapter 12 - Object Serialization and the .NET Remoting Layer

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

The "lock" keyword will be examined later in this text during our formal examination of multithreaded

Chapter 14 - A Better Painting Framework (GDI+)

programming (see Chapter 10). The remaining members of the preceding list ("checked", "unchecked",

Chapter 15 - Programming with Windows Forms Controls

"unsafe", "stackalloc", "fixed", "volatile", and "sizeof") will be the focus of the first part of this chapter. To

Chapter 16 - The System.IO Namespace

start, let's check out how C# provides automatic detection of arithmetic overflow (and underflow).

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

The "checked" Keyword

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

As you are well aware, each numerical data type has a fixed upper and lower limit (which may be obtained

Chapter 20 - XML Web Services

programmatically using the MaxValue/MinValue properties). Now, when you are performing arithmetic

Index

operations on a specific type, it is very possible that you may accidentally overflow the maximum storage

List of Figures

of the type (assign a value that is greater than the maximum value) or underflow the minimum storage of

List of Tables

the type (assign a value that is less than the minimum value). To keep in step with the CLR, I will refer to both of these possibilities collectively as "overflow." (As you will see, both overflow and underflow conditions result in a System.OverflowException type. There is no System.UnderflowException type in the base class libraries.)

To illustrate the issue, assume you have created two System.Byte types, each of which have been assigned a value that is safely below the maximum value (255). If you were to add the values of these types (casting the result as a byte) and print out the result, you would assume that the result would be the exact sum of each member:

namespace CheckedUnchecked

{

class TheChecker

{

static void Main(string[] args)

{

// Overflow the max value of a System.Byte.

C# and the .NET Platform, Second Edition

Console.WriteLine("Max value of byte is {0}.", byte.MaxValue);

by Andrew Troelsen ISBN:1590590554

Console.WriteLine("Min value of byte is {0}.", byte.MinValue);

Apress © 2003 (1200 pages)

byte b1 = 100;

This comprehensive text starts with a brief overview of the byte b2 = 250;

C# language and then quickly moves to key technical and byte b3 = (byte)(b1 + b2);

architectural issues for .NET developers.

// b3 should hold the value 350, however...

Console.WriteLine("b3 = {0}", b3);

}

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

If you were to view the output of this application, you might be surprised to find that b3 contains the value

Chapter 2 - Building C# Applications

94 (rather than the expected 350). The reason is simple. Given that a System.Byte can only hold a value PartbetweenTwo -0TheandC#255Programming(inclusive, forLanguagea grand total of 256 slots), b3 now contains the overflow value (350 – Chapter256 = 94)3 .-AsC#youLanguagehave justFundamentalsseen, if you take no corrective course of action, overflow occurs without

Chapterexception4 .-AtObjecttimes,-Orientedthis hiddenProgrammingoverflow maywith causeC# no harm whatsoever in your project. Other times, this

Chapterloss of 5data- Exis completelyeptions andunacceptableObje Lifetime.

Chapter 6 - Interfaces and Collections

To handle overflow or underflow conditions in your application, you have two possibilities. Your first choice

Chapter 7 - Callback Interfaces, Delegates, and Events

is to leverage your wits and programming skills to handle all overflow conditions manually. Assuming you

Chapter 8 - Advanced C# Type Construction Techniques

were indeed able to find each overflow condition in your program, you could resolve the previous overflow

Part Three - Programming with .NET Assemblies

error as follows:

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

// Store sum in an integer to prevent overflow.

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

byte b1 = 100;

Part Four - Leveraging the .NET Libraries

byte b2 = 250;

Chapter 12 - Object Serialization and the .NET Remoting Layer int answer = b1 + b2;

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

Chapter 15 - Programming with Windows Forms Controls

ChapterOf course,16 -theTheproblemSyst .IOwithNamespacethis technique is the simple fact that we are humans, and even our best

Chapterattempts17may- DataresultAccessin errorswith ADOthat.NEThave escaped our eyes. Given this, C# provides the "checked" keyword.

PartWhenFiveyou- WebwrapApplica statementtions and(orXMLblockWebof Servicesstatements) within the scope of the "checked" keyword, the C#

Chaptercompiler18will- ASPemit.NETspecificWeb PagesCIL instructionsand Web Controlsthat test for overflow conditions that may result when adding, Chaptermultiplying,19 - subtracting,ASP.NET WeborApplicationsdividing two numerical data types. If an overflow has occurred, the runtime will

throw a System.OverflowException type. To illustrate, observe the following update:

Chapter 20 - XML Web Services

Index

Listclassof FiguresTheChecker

List{ of Tables

static void Main(string[] args)

{

// Overflow the max value of a System.Byte.

Console.WriteLine("Max value of byte is {0}.", byte.MaxValue); byte b1 = 100;

byte b2 = 250; try

{

byte b3 = checked((byte)(b1 + b2)); Console.WriteLine("b3 = {0}", b3);

}

catch(OverflowException e)

{ Console.WriteLine(e.Message); }

}

}

C# and the .NET Platform, Second Edition

Here, you wrap the addition of b1 and b2 within the scope of the "checked" keyword. If you wish to force

by Andrew Troelsen ISBN:1590590554

overflow checking to occur over a block of code, you can interact with the "checked" keyword as follows:

Apress © 2003 (1200 pages)

try

{

checked

{

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 Contenbytes b3 = (byte)(b1 + b2);

C# and the .NETbytePlatform,b4, b5Second= 100,Editionb6 = 200;

Introduction b4 = (byte)(b5 + b6);

Console.WriteLine("b3 = {0}", b3);

Part One - Introducing C# and the .NET Platform

Chapter}1 - The Philosophy of .NET

}

Chapter 2 - Building C# Applications

catch(OverflowException e)

Part Two - The C# Programming Language

{

Chapter 3 - C# Language Fundamentals

Console.WriteLine(e.Message);

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

In either case, the code in question will be evaluated for possible overflow conditions automatically, which

Chapter 8 - Advanced C# Type Construction Techniques will trigger an overflow exception.

Part Three - Programming with .NET Assemblies

ChapSettinger 9 -ProjectUnd rs anding-Wide.NETOverflowAssembliesChecking

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Now, if you are creating an application that should never allow silent overflow to occur, you may find

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

yourself in the annoying position of wrapping numerous lines of code within the scope of the "checked"

Part Four - Leveraging the .NET Libraries

keyword. As an alternative, the C# compiler supports the /checked flag. When enabled, all of your

Chapter 12 - Object Serialization and the .NET Remoting Layer

arithmetic will be evaluated for overflow without the need to make use of the C# "checked" keyword. If

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

overflow has been discovered, you will still receive a runtime exception. To enable this flag under VS

Chapter 14 - A Better Painting Framework (GDI+)

.NET, activate the Check for Arithmetic Overflow/Underflow option from the project's property page

Chapter 15 - Programming with Windows Forms Controls

(Figure 8-1).

Chapter 16 - The System.IO Namespace

Chapter 17 - Data Access with ADO.NET

Part

Chapter

Chapter

Chapter

Index

List of

List of

Figure 8-1: Enabling VS .NET overflow checking

As you may guess, this technique can be very helpful when creating a debug build. Once all of the overflow exceptions have been squashed out of the code base, you are free to disable the /checked flag for subsequent builds (which will increase the runtime execution of your application).

The "unchecked" Keyword

Now, assuming you have enabled this project-wide setting, what are you to do if you have a block of code

C# and the .NET Platform, Second Edition

 

where silent overflow is acceptable? Given that the /checked flag will evaluate all arithmetic logic, the C#

by Andrew Troelsen

ISBN:1590590554

language provides the "unchecked" keyword to disable the throwing of System.OverflowException on a

Apress © 2003 (1200 pages)

case-by-case basis. The use of this keyword is identical to the "checked" keyword in that you can specify a

This comprehensivestatementst xt starts with a brief overview of the single statement or a block of . For example:

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

//Assuming +checked is enabled,

//this block will not trigger

Table// aof ruContimeents exception.

unchecked

C# and the .NET Platform, Second Edition

{

Introduction

byte b3 = (byte)(b1 + b2);

Part One - Introducing C# and the .NET Platform

Console.WriteLine("b3 = {0}", b3);

Chapter 1 - The Philosophy of .NET

}

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

So, to summarize the C# "checked" and "unchecked" keywords, recall that the default behavior of the

Chapter 4 - Object-Oriented Programming with C#

.NET runtime is to ignore arithmetic overflow. When you want to selectively handle discrete statements,

Chapter 5 - Exceptions and Object Lifetime

make use of the "checked" keyword. If you wish to trap overflow errors throughout your application, enable

Chapter 6 - Interfaces and Collections

the +checked flag. Finally, the "unchecked" keyword may be used if you have a block of code where

Chapter 7 - Callback Interfaces, Delegates, and Events

overflow is acceptable (and thus should not trigger a runtime exception).

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Regarding Underflow Conditions

Chapter 9 - Understanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Finally, recall that there is no System.UnderflowException type within the .NET base class libraries.

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

Rather, in the event of an underflow condition, the runtime will again throw an OverflowException:

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

// Underflow conditions also trigger an OverflowException!

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

Chapter 14 - A Better Painting Framework (GDI+)

{

Chapter 15 - Programming with Windows Forms Controls byte a = 9, b = 9;

Chapter 16 - The System.IO Namespace // c is less than zero! byte c = (byte)(a + b + -100);

Chapter} 17 - Data Access with ADO.NET

Partcatch(OverflowExceptionFive - W b Applications and XMLe){ConsoleWeb Services.WriteLine(e);}

Chapter 18 - ASP.NET Web Pages and Web Controls

Chapter 19 - ASP.NET Web Applications

Chapter 20 - XML Web Services

IndexSOURCE The CheckedUnchecked project can be found under the Chapter 8 subdirectory.

CODE

List of Figures

List of Tables

Working with "Unsafe" Code

Next up, we have three keywords that allow the C# programmer to bypass the CLR's memory management scheme in order to take matters into their own hands. In a nutshell, this allows C# programmers to make use of C(++) style pointers. Given this, C# does indeed provide additional operators specifically for this purpose (see Table 8-1).

Table 8-1: Pointer-Centric C# Operators

Chapter 17 - Data Access with ADO.NET
Chapter 16 - The System.IO Namespace

 

C# Pointer-C# and

 

theMeaning.NET Platform,in LifeSecond Edition

 

 

Centric

by Andrew

Troelsen

ISBN:1590590554

 

Operator

Apress ©

 

2003 (1200 pages)

 

 

 

 

 

 

 

 

*

 

This

comprehensive text starts with a brief overview of the

 

 

 

 

Used to create a pointer variable, a variable that represents a direct

 

 

 

C# language and then quickly moves to key technical and

 

 

 

architecturallocationissuesinformemory..NET developers.Like C(++), this same operator is used to represent

 

 

 

 

 

pointer indirection.

 

 

 

 

 

 

 

&

 

 

 

Used to obtain the address of a pointer.

Table of Contents

 

 

 

 

 

 

 

 

C#and> the .NET Platform,

 

SecondThis operatorEdition is used to access fields of a type that is represented by a

Introduction

 

 

pointer variable (the unsafe version of the C# dot operator).

 

 

 

 

 

Part One - Introducing C#

and the .NET Platform

 

[]

- The Philosophy

 

The [] operator (in an unsafe context) allows you to index the slot pointed

Chapter 1

of .NET

 

Chapter 2

- Building C#

 

to by a pointer variable (recall the interplay between a pointer variable

Applications

 

 

 

 

 

 

and the [] operator in C(++)!).

 

Part Two - The C# Programming Language

Chapter 3 - C# Language Fundamentals

ChapterNow, before4 - Objectwe dig-Orieninto theed Programmingdetails, let mewithpointC#out the fact that you will seldom ifever need to make use

Chaptof thertechniques5 - Exc ptionswe areandaboutObjecttoLifetiexamine. Although C# does allow you to drop down to the level of Chapterpointer6manipulations,- Interfaces understandCollectionsthat the .NET runtime has absolutely no clue of your intentions. Thus, if

you mismanage a pointer, you are the one in charge of dealing with the consequences. Given these

Chapter 7 - Callback Interfaces, Delegates, and Events

warnings, when exactly would you need to work with unsafe code (and therefore the operators seen in

Chapter 8 - Advanced C# Type Construction Techniques

Table 8-1)? There are two common situations:

Part Three - Programming with .NET Assemblies

Chapter 9 - Understanding .NET Assemblies

You are looking to optimize select parts of your application by bypassing the CLR. For example, you

Chapter 10 - Processes, AppDomains, Contexts, and Threads

want to build a function that copies an array using pointer arithmetic.

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

Part FourYou-areL veragingattemptingtheto.NETtriggerLibrariesthe functionality of a C-based *.dll (such as the Win32 API or a custom

ChapterC-based12 - Object*.dll) Serializationand need toandcreatethepointer.NET RemotingvariablesLayerto call various methods.

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

Beyond these two reasons, there will never be a need to declare, dereference, or manipulate direct

Chapter 14 - A Better Painting Framework (GDI+)

pointers using C#. In the event that you decide to make use of this C# language feature, you will also be

Chapter 15 - Programming with Windows Forms Controls

required to inform csc.exe of your intent! If you are making use of csc.exe in the raw, be sure you supply the /unsafe flag. From VS .NET, you will need to access your project's Property page and enable the

Allow Unsafe Code Blocks setting (Figure 8-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 8-2: Enabling VS .NET unsafe compilation

Now let's ponder the basics. In the examples that follow, I'm assuming that you do have some background in C(++) pointer manipulations. If this is not true in your case, don't sweat it. Again, writing unsafe code will not be a common task for a huge majority of .NET applications.

The "Unsafe" Keyword

C# and the .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

When you wish to work with pointers in C#, you must specifically declare a block of "unsafe" code using

Apress © 2003 (1200 pages)

the "unsafe" keyword (as you might guess, any code that is not marked with the "unsafe" keyword is

This comprehensive text starts with a brief overview of the considered "safe" automatically, thus there is not a "safe" keyword in C#):

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

unsafe

{

Table of Contents

// Work with pointers here!

C# and the .NET Platform, Second Edition

}

Introduction

Part One - Introducing C# and the .NET Platform

In addition to declaring a scope of unsafe code, you are able to build structures, classes, type members,

Chapter 1 - The Philosophy of .NET

and parameters that are "unsafe." Here are a few examples to gnaw on:

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

Chapter// This3 -entireC# LanguagestructureFundamentalsis 'unsafe' and can

// only be used in an unsafe context.

Chapter 4 - Object-Oriented Programming with C#

publicunsafe struct Node

Chapter 5 - Exceptions and Object Lifetime

{

Chapter 6 - Interfaces and Collections

public int Value;

Chapter 7 - Callback Interfaces, Delegates, and Events

public Node* Left;

Chapter 8 - Advanced C# Type Construction Techniques

public Node* Right;

Part Three - Programming with .NET Assemblies

}

Chapter 9 - Understanding .NET Assemblies

// This struct is safe, but the Node* members

Chapter 10 - Processes, AppDomains, Contexts, and Threads

// are not. Technically, you may access 'Value' from

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

// outside a unsafe context, but not 'Left' and 'Right'.

Part Four - Leveraging the .NET Libraries

public struct Node

Chapter 12 - Object Serialization and the .NET Remoting Layer

{

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

public int Value;

Chapter 14 - A Better Painting Framework (GDI+)

// These can only be accessed in an unsafe context!

Chapter 15 - Programming with Windows Forms Controls public unsafe Node* Left;

Chapter 16 - The System.IO Namespace

public unsafe Node* Right;

Chapter} 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

Methods (static or instance level) may be marked as unsafe as well. For example, assume that you know

Chapter 19 - ASP.NET Web Applications

a given static method will make use of pointer logic. To ensure that this method can only be called from an

Chapter 20 - XML Web Services

unsafe context, you could define the method as follows:

Index

List of Figures

unsafe public static void SomeUnsafeCode()

List of Tables

{

// Work with pointers here!

}

This configuration would demand that the caller invoke SomeUnsafeCode() as so:

static void Main()

{

unsafe{SomeUnsafeCode();}

}

Conversely, if you would rather not force the caller to wrap the invocation within an unsafe context, you could remove the "unsafe" keyword from the SomeUnsafeCode() method signature and opt for the following:

C# and the .NET Platform, Second Edition public static void SomeUnsafeCode()

by Andrew Troelsen

ISBN:1590590554

{

 

Apress © 2003 (1200 pages)

 

unsafe

This comprehensive text starts with a brief overview of the

{

C# language and then quickly moves to key technical and

// Work with pointers here! architectural issues for .NET developers.

}

}

Table of Contents

C# and the .NET Platform, Second Edition

Introduction

which would simplify the call to:

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

static void Main()

Chapter 2 - Building C# Applications

{

Part Two - The C# Programming Language

SomeUnsafeCode();

Chapter 3 - C# Language Fundamentals

}

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

Chapter 6 - Interfaces and Collections

Working with the * and & Operators

Chapter 7 - Callback Interfaces, Delegates, and Events

ChaptOnceryou8 -haveAdvancedestablishedC# TypeanConstructionunsafe context,Techniquesyou are then free to build pointers to data types using the *

PartoperatorThreeas- Progrwell asmmingobtainwiththe.addressNET A embliesof said pointer using the & operator. Using C#, the * operator is

Chaappliedter 9to-theUnderstandingunderlying type.NETonly,Assembliesnot as a prefix to each pointer variable name. For example, the

Chapterfollowing10declares- Proc ses,twoAppDomains,variables, bothContexts,of type int*and(aThreadspointer to an integer).

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

Part Four - Leveraging the .NET Libraries

// No! This is incorrect under C#!

Chapter 12 - Object Serialization and the .NET Remoting Layer int *pi, *pj;

Chapter// Yes!13 -ThisBu ldingisa Betterthe wayWindofw (IntroducingC#. Windows Forms)

Chapint*er pi,14 - Apj;Better Painting Framework (GDI+)

Chapter 15 - Programming with Windows Forms Controls

Chapter 16 - The System.IO Namespace

Given this, check out the following example:

Chapter 17 - Data Access with ADO.NET

Part Five - Web Applications and XML Web Services

unsafe

Chapter 18 - ASP.NET Web Pages and Web Controls

{

Chapter 19 - ASP.NET Web Applications

int myInt;

Chapter 20 - XML Web Services

Index // Define an int pointer, and

// assign it the address of myInt.

List of Figures

int* ptrToMyInt = &myInt;

List of Tables

// Assign value of myInt using pointer indirection.

*ptrToMyInt = 123;

// Print some stats.

Console.WriteLine("Value of myInt {0}", myInt);

Console.WriteLine("Address of myInt {0:X}", (int)ptrToMyInt);

}

An Unsafe (and Safe) Swap Function

Of course, declaring pointers to local variables simply to assign their value (as shown in the previous example) is never required. To illustrate a more useful example of unsafe code, assume you wish to build a swap function using pointer arithmetic:

unsafe public static void UnsafeSwap(int* i, int* j)

{

Chapter 10 - Processes, AppDomains, Contexts, and Threads
Chapter 9 - Understanding .NET Assemblies

int temp = *i;

C# and the .NET Platform, Second Edition

*i = *j;

by Andrew Troelsen

ISBN:1590590554

*j = temp;

 

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

Very C-like, don't you think? However, given your work in Chapter 3, you should be aware that you could

write the following safe version of your swap algorithm using the C# "ref" keyword:

Table of Contents

C# and the .NET Platform, Second Edition

public static void SafeSwap(ref int i, ref int j)

Introduction

{

Part One - Introducing C# and the .NET Platform

int temp = i;

Chapter 1 - The Philosophy of .NET

i = j;

Chapter 2 - Building C# Applications

j = temp;

Part Two - The C# Programming Language

}

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

ChapterThe functionality5 - Exceptionsof eachandmethodObject isLifetimeidentical, thus reinforcing the point that direct pointer manipulation is

Chapternot a mandatory6 - Interftaskcesundera CollectionsC#.

Chapter 7 - Callback Interfaces, Delegates, and Events

Field Access via Pointers (the –> Operator)

Chapter 8 - Advanced C# Type Construction Techniques

Part Three - Programming with .NET Assemblies

Now assume that you have a Point structure and wish to declare a pointer to a Point type. Like C(++), when you wish to invoke methods or trigger fields of a pointer type, you will need to make use of the

pointer-field access operator (–>). As mentioned in Table 8-1, this is the unsafe version of the standard

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

(safe) dot operator (.). In fact, using the pointer indirection operator (*), it is possible to dereference a

Part Four - Leveraging the .NET Libraries

pointer to (once again) apply the dot operator notation. Check out the following:

Chapter 12 - Object Serialization and the .NET Remoting Layer

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

Chapter 14 - A Better Painting Framework (GDI+)

{

Chapter 15 - Programming with Windows Forms Controls public int x;

Chapter 16 - The System.IO Namespace public int y;

Chapter 17 - Data Access with ADO.NET

public override string ToString()

Part Five - Web Applications and XML Web Services

{ return "(" + x + "," + y + ")"; }

Chapter 18 - ASP.NET Web Pages and Web Controls

}

Chapter 19 - ASP.NET Web Applications

static void Main(string[] args)

Chapter 20 - XML Web Services

{

Index // Access members via pointer.

List of Figuresunsafe

List of Tables{

Point point;

Point* p = &point;

p->x = 100;

p->y = 200;

Console.WriteLine(p->ToString());

}

// Access members via pointer indirection.

unsafe

{

Point point;

Point* p = &point;

(*p).x = 100;

(*p).y = 200;

Console.WriteLine((*p).ToString());

}

}

C# and the .NET Platform, Second Edition

 

by Andrew Troelsen

ISBN:1590590554

Apress © 2003 (1200 pages)

The "stackalloc"This comprehensiveKeyword text starts with a brief overview of the

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

In an unsafe context, you may need to declare a local variable that allocates memory directly from the call stack (and is therefore not subject to .NET garbage collection). To do so, C# provides the "stackalloc"

keyword, which is the C# equivalent to the _alloca function of the C runtime library. Here is a simple

Table of Contents example:

C# and the .NET Platform, Second Edition

Introduction

unsafe

Part One - Introducing C# and the .NET Platform

{

Chapter 1 - The Philosophy of .NET

char* p = stackalloc char[256];

Chapter 2 - Building C# Applications

for (int k = 0; k < 256; k++)

Part Two - The C# Programming Language

p[k] = (char)k;

Chapter 3 - C# Language Fundamentals

}

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

ChapterPinning6 -aInterfacesType viaandtheCollect"fixed"ons Keyword

Chapter 7 - Callback Interfaces, Delegates, and Events

As seen in the previous example, allocating a chunk of memory within an unsafe context may be facilitated

Chapt r 8 - Advanced C# Type Construction Techniques

via the "stackalloc" keyword. By the very nature of this operation, the allocated memory is cleaned up as

Part Three - Programming with .NET Assemblies

soon as the allocating method has returned (as the memory is acquired from the stack). However,

Chapter 9 - Understanding .NET Assemblies

assume a more complex example. During our examination of the –> operator, you created a value type

Chapter 10 - Processes, AppDomains, Contexts, and Threads

named Point. Like all value types, the allocated memory is popped off the stack once the executing scope

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

has terminated. For the sake of argument, assume Point was instead defined as a reference type:

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

class Point // <= Now a class!

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

{

Chapter 14 - A Better Painting Framework (GDI+)

public int x;

Chapter 15 - Programming with Windows Forms Controls

public int y;

Chapter 16 - The System.IO Namespace

public override string ToString()

Chapter 17 - Data Access with ADO.NET

{ return "(" + x + "," + y + ")"; }

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 Servicthes

As you are well aware, if caller declares a variable of type Point, the memory is allocated on the

Indexgarbage collected heap. The burning question then becomes: What if an unsafe context wishes to interact

ListwithofthisF gurestype (or any type on the heap)? Given that garbage collection can occur at any given moment

List(seeofChapterTables 5), imagine the pain of accessing the members of Point at the very time in which a sweep of the heap is underway. Theoretically, it is possible that the unsafe context is attempting to interact with a member that is no longer accessible or has been repositioned on the heap after surviving a generational sweep (which is an obvious problem).

To lock a reference type variable in memory from an unsafe context, C# provides the "fixed" keyword. The fixed statement sets a pointer to a managed type and "pins" that variable during the execution of statement. Without "fixed", pointers to managed variables would be of little use, since garbage collection could relocate the variables unpredictably. (In fact, the C# compiler will not allow you to set a pointer to a managed variable except in a fixed statement.) Thus, if you were to create a Point type (now redesigned as a class) and wish to interact with its members, you must write the following code (or receive a compiler error):

unsafe public static void Main()

{

Point pt = new Point();

pt.x = 5;

 

C# and the .NET Platform, Second Edition

 

pt.y = 6;

 

ISBN:1590590554

 

by Andrew Troelsen

 

// pin pt in place so it will not

 

 

Apress © 2003 (1200 pages)

 

 

// be moved or GC-ed.

 

 

fixed

This comprehensive text starts with a brief overview of the

(int* p = &pt.x)

 

 

{

C# language and then quickly moves to key technical and

architectural issues for .NET developers.

 

}

// Use int* variable here!

 

 

 

 

Table of //Contentspt is now unpinned, and ready to be GC-ed.

C# and theConsole.WriteLine.NET Platform, Second("PointEdition

is: {0}", pt);

}

 

 

 

Introduction

 

 

 

Part One - Introducing C# and the .NET Platform

Chapter 1 - The Philosophy of .NET

In a nutshell, the "fixed" keyword allows you to build a statement that locks a reference variable in

Chapter 2 - Building C# Applications

memory, such that its address remains constant for the duration of the statement. To be sure, any time

Part Two - The C# Programming Language

you interact with a reference type from within the context of unsafe code, pinning the reference is a must.

Chapter 3 - C# Language Fundamentals

Chapter 4

- Object-Oriented Programming with C#

The "volatile" Keyword

Chapter 5

- Exceptions and Object Lifetime

Chapter 6

- Interfaces and Coll ctions

The next (and arguably most exotic) C# keyword we will consider is "volatile". In effect, when you define a

Chapter 7

- Callback Int rfaces, Delegat s, a d Ev nts

volatile variable, you are performing the converse operation of pinning a type in memory, in that you are

Chaptertelling the8 -runtimeAdvancedthatC#it isTypecompletelyConstructionfine toTechniquesallow an outside agent (such as the operating system, the

Parthardware,Three -orProgrammingconcurrentlywithexecuting.NET Assembliesthread) to modify the item in question at any time. Declaring such a

Chvariablepter 9is-simple:Und rstanding .NET Assemblies

Chapter 10 - Processes, AppDomains, Contexts, and Threads

Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming volatile int moveMeAnytime;

Part Four - Leveraging the .NET Libraries

Chapter 12 - Object Serialization and the .NET Remoting Layer

Basically, the "volatile" keyword may be used to define a type field that is accessed by multiple threads

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

without using the lock statement (examined in Chapter 10) to serialize access. Using the "volatile" modifier

Chapter 14 - A Better Painting Framework (GDI+)

ensures that one thread retrieves the most up-to-date value written by another thread. Again, we have not

Chapter 15 - Programming with Windows Forms Controls

examined threads at this point in the game, so for the time being, simply understand that this C# keyword

Chapter 16 - The System.IO Namespace

ensures that all threads will observe volatile write operations performed by a given thread in the order they

Chapter 17 - Data Access with ADO.NET were performed.

Part Five - Web Applications and XML Web Services

Chapter 18 - ASP.NET Web Pages and Web Controls

To be completely honest, you will more than likely never make use of this keyword, given that the

ChaptSystemr 19 - ASP.NET Web Applicatiprovidesns

.Threading namespace you with numerous synchronization primitives that achieve the Chsamept reffect20 - .XMLIn fact,WebC#Servicesis one of the very few .NET-aware languages that provide a keyword such as

Index"volatile".

List of Figures

ListTheof Tables"sizeof" Keyword

The final advanced C# keyword to consider is "sizeof". Like C(++), the "sizeof" keyword is used to obtain the size in bytes for a value type (never reference types), and may only be applied from within an unsafe context. As you may imagine, this ability may prove helpful when interacting with unmanaged C-based APIs. Its usage is straightforward:

Console.WriteLine("The size of short is {0}.", sizeof(short)); Console.WriteLine("The size of int is {0}.", sizeof(int)); Console.WriteLine("The size of long is {0}.", sizeof(long));

As "sizeof" will evaluate the number of bytes for any System.ValueType-derived entity, you are able to

obtain the size of custom structures as well:

struct MyValueType

{

C# and the .NET Platform, Second Edition

 

public short s;

ISBN:1590590554

by Andrew Troelsen

public int i;

 

Apress © 2003 (1200 pages)

 

public long l;

 

}This comprehensive text starts with a brief overview of the

C# language and then quickly moves to key technical and

Console.WriteLine("The size of MyValueType is {0}.", architectural issues for .NET developers.

sizeof(MyValueType));

Table of Contents

C# and the .NET Platform, Second Edition

SOURCE The UnsafeCode project can be found under the Chapter 8 subdirectory.

Introduction

CODE

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

A Catalog ofC#C#and Keywordsthe .NET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

At this point in the text, you have used of a majority of C# keywords. Beyond the "lock" (see Chapter 10),

Apress © 2003 (1200 pages)

"typeof" (see Chapter 11), and "extern" (used via P/Invoke operations) keywords, the remaining tokens of

This comprehensive text starts with a brief overview of the

interest are "explicit"C# landguage"implicit",and thenwhichquicklywill bemovesexaminedto keyatechnicalbit later andin this chapter. For your convenience, Table 8-2 lists thearcompletehitecturalsetissuesof keywordsfor .NET developerscurrently supported. by C#, grouped by related functionality.

Table 8-2: A Summary of C# Keywords

Table of Contents

 

EditionMeaning in Life

 

C#C#andKeywordthe .NET Platform, Second

 

 

 

 

 

 

 

 

Introduction

 

These C# keywords are simply aliases to structures in the System

 

 

bool, byte, char, float, uint,

 

 

Part One - Introducing C# and the

 

.NET Platform

 

 

ulong, ushort, decimal, int,

 

namespace. Collectively, they represent the core data types of

 

Chapter

1

- The Philosophy of .NET

 

 

sbyte, short, void, double,

 

the CTS (recall that unsigned types are not CLS compliant).

 

Chapter

2

- Building C# Applications

 

 

long, string, object

 

 

 

Part Two - The C# Programming

 

Language

 

 

 

Chapternull

3

- C# Language FundamentalsThe "null" keyword is a literal that represents a null reference,

 

 

Chapter

4

 

 

one that does not refer to any object.

 

 

- Object-Oriented Programming with C#

 

 

 

 

 

 

 

 

 

Chapter

5

- Exceptions and Object

 

Lifetime

 

 

true, false

 

These keywords represent the possible values that can be

 

 

Chapter

6

- Interfaces and Collections

 

 

 

 

 

 

assigned to a System.Boolean type.

 

 

 

 

 

 

 

 

 

Chapter

7

- Callback Interfaces,

 

Delegates, and Events

 

 

out, ref, params

 

These keywords are used to control how parameters are passed

 

 

Chapter

8

- Advanced C# Type

 

Construction Techniques

 

 

 

 

 

 

into (and out from) a type member.

 

Part Three - Programming with .NET Assemblies

 

 

Chapter

9

- Understanding .NET

 

Assemblies

 

 

public, private, internal,

 

These keywords are used to control the visibility of types and their

 

 

Chapter

10

- Processes, AppDomains,

Cont xts, and Threads

 

 

protected

 

members.

 

 

 

 

 

 

 

 

 

Chapter

11

- Type Reflection, Late

 

Binding, and Attribute-Based Programming

 

 

class, interface, struct,

 

These C# keywords are used to build custom CTS types and type

 

Part Four - Leveraging the .NET

 

Libraries

 

 

enum, delegate, event

 

members (e.g., the "event" keyword).

 

 

Chapter

12

- Object Serialization and the .NET Remoting Layer

 

 

 

 

Chapterreturn13

- Building a Better WindowThis(Introducingkeyword isWindowsused to designateForms) the return value of a type

 

 

Chapter

14

- A Better Painting Frameworkmember(GDI+).

 

 

 

 

 

 

 

 

 

Chapter

15

- Programming with

 

Windows Forms Controls

 

 

as, is

16

 

 

These keywords are used to determine at runtime if one type is

 

 

Chapter

- The System.IO Namespace

 

 

 

 

 

 

compatible with another type.

 

 

Chapter

17

- Data Access with ADO.NET

 

 

 

Partdo,Fivewhile,- Webforeach,Applicationsin, for and XMLTheseWebC#Serviceskeywords represent the set of language iteration

 

 

Chapter

18

- ASP.NET Web Pages

andconstructs.Web Controls

 

 

 

 

 

 

 

 

 

Chapter

19

- ASP.NET Web Applications

 

 

if, else, switch, case,

 

These C# keywords represent the set of language decision

 

 

Chapter

20

- XML Web Services

 

constructs.

 

 

default, break

 

 

Index

 

 

 

 

 

 

 

 

These keywords work in conjunction with the decision and

 

 

goto, continue

 

 

List of Figures

 

iteration constructs to further refine control flow.

 

List of Tables

 

 

 

 

 

 

try, catch, throw, finally

 

These keywords are used to handle runtime exceptions.

 

 

 

 

 

 

 

operator, explicit, implicit

 

These C# keywords are used to build types that support

 

 

 

 

 

 

overloaded operators and custom conversion routines (keep

 

 

 

 

 

 

reading . . .).

 

this, base

abstract, virtual, override

namespace

These keywords are used to reference the current object or a reference type's base class.

These C# keywords allow you to incorporate polymorphism into your class hierarchies.

This keyword defines a custom namespace that contains your custom types.

 

 

 

 

 

 

 

 

 

 

 

using

 

C# and the .NETThisPlatform,single keywordSecond Editioncan be used under two circumstances:

 

 

 

by Andrew Troelsen

ISBN:1590590554

 

 

 

Apress © 2003 (1200 pages) Namespace referencing

 

 

 

This comprehensive text starts with a brief overview of the

 

 

 

C# language and then

 

quicklyAutomaticmovesdisposalto key technicalof an objectand

 

 

 

 

 

 

 

 

 

 

 

 

 

new

 

architectural issues for .NET developers.

 

 

 

 

 

 

This single keyword also has a dual identity:

Table of Contents

 

 

 

 

 

Type allocation

 

 

 

 

 

 

 

 

 

 

 

 

 

C# and the .NET Platform, Second Edition

 

 

Introduction

 

 

 

 

 

Shadowing inherited members

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Part One - Introducing C# and the

 

 

.NET Platform

 

 

const

 

 

 

 

This keyword allows you to create a constant (e.g.,

Chapter 1 - The Philosophy of .NETunchangeable) point of data.

 

 

 

 

 

 

Chapter 2 - Building C# Applications

 

 

 

 

 

Partchecked,Two - TheuncheckedC# Programming

LanguageThese C# keywords are used to control the overflow-checking

 

 

 

 

 

 

context for arithmetic operations and conversions.

 

Chapter 3 - C# Language Fundamentals

 

 

 

 

 

 

 

 

Chapter 4 - Object-Oriented Programming with C#

 

 

unsafe, fixed, stackalloc

 

 

These keywords are used when declaring (or using) an unsafe

 

Chapter 5 - Exceptions and Object Lifetime

 

 

 

 

 

 

 

context, which is required when interacting with memory pointers

 

Chapter 6

- Interfaces and Collections

 

 

 

 

 

 

 

using C#.

 

 

 

 

 

 

 

 

Chapter 7 - Callback Interfaces,

 

Delegates, and Events

 

 

extern

- Advanced C# Type

 

 

While we have not made use of this keyword, "extern" allows you

 

Chapter 8

 

 

Construction Techniques

 

 

 

 

 

 

 

to qualify that a member is defined in an external C-based

Part Three - Programming with .NET Assemblies

 

 

 

 

 

 

 

module (used during PInvoke operations).

 

Chapter 9 - Understanding .NET

 

 

Assemblies

 

Chaptersealed10 - Processes, AppDomains,ThisContexts,keywordandis usedThreadsto build class types that cannot be extended.

 

Chapter 11 - Type Reflection, Late

 

Binding, and Attribute-Based Programming

 

 

sizeof

 

The "sizeof" operator is used to obtain the size in bytes for a value

 

Part Four - Leveraging the .NET

Libraries

 

 

 

 

type.

 

 

Chapter 12 - Object Serialization and the .NET Remoting Layer

 

 

 

 

Chaptervolatile13 - Building a Better WindowThis(Introducingkeyword indicatesWindowsthatForms)a field can be modified at any time,

 

 

Chapter 14 - A Better Painting Frameworkwithout(GDI+)error, in the program by something such as the operating

 

 

Chapter 15 - Programming with

Windowssystem,Formsthe hardware,Controls or a concurrently executing thread.

 

 

 

 

 

 

 

Chapter 16 - The System.IO Namespace

 

 

static

 

This keyword is used to define a member (or data point) that is

 

 

Chapter 17 - Data Access with ADO.NET

 

 

 

 

shared by all instances of the defining type.

 

Part Five - Web Applications and

XML Web Services

 

 

 

lock

 

We have not yet examined this C# keyword; however, as you will

 

Chapter 18 - ASP.NET Web Pages

and Web Controls

 

 

 

 

see during our examination of multithreaded programming, "lock"

 

Chapter 19 - ASP.NET Web Applications

 

 

Chapter 20 - XML Web Services

 

can be used to mark a block of code that is thread safe.

 

 

 

 

 

Ind x

 

This keyword declares a field that can only be assigned values as

 

 

readonly

 

 

List of Figures

 

part of the declaration or in a constructor in the same class.

 

 

 

 

 

 

List of Tables

 

Again, we have not formally investigated this keyword; however,

 

 

typeof

 

 

 

 

 

as you will see during our examination of System.Reflection

 

 

 

 

(Chapter 11), "typeof" allows you to obtain a System.Type

 

 

 

 

variable that contains the metadata descriptors for the entity sent

 

 

 

 

into the typeof operator.

 

Now that you have the bulk of the C# language keywords under your belt, we can direct our attention to the finer details of building C# types, beginning with the concept of an indexer.

Building a Custom# and the .IndexerNET Platform, Second Edition

by Andrew Troelsen

ISBN:1590590554

As programmers, we are very familiar with the process of accessing discrete items held within a standard

Apress © 2003 (1200 pages)

array using the index (aka bracket) operator:

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.

// Declare an array of integers.

int[] myInts = { 10, 9, 100, 432, 9874};

// Use the [] operator to access each element.

Table of Contents

for(int j = 0; j < myInts.Length; j++)

C# and the .NET Platform, Second Edition

Console.WriteLine("Index {0} = {1} ", j, myInts[j]);

Introduction

Part One - Introducing C# and the .NET Platform

ChapterThe previous1 - ThecodePhilosophyis by noofmeans.NET a major news flash. However, the C# language provides the capability

Chapterto build2custom- BuildingclassesC# Applicationsthat may be indexed just like an array of intrinsic types. It should be no big surprise

PartthatTwothe -methodThe C#thatProgrammingprovides theLanguagecapability to access items in this manner is termed an indexer.

Chapter 3 - C# Language Fundamentals

Before exploring how to create such a construct, let's begin by seeing one in action. Assume you have

Chapter 4 - Object-Oriented Programming with C#

added support for an indexer method to the Cars container developed in Chapter 6. Observe the following

Chapter 5 - Exceptions and Object Lifetime

usage:

Chapter 6 - Interfaces and Collections

Chapter 7 - Callback Interfaces, Delegates, and Events

// Indexers allow you to access items in an array-like fashion.

Chapter 8 - Advanced C# Type Construction Techniques

public class CarApp

Part Three - Programming with .NET Assemblies

{

Chapter 9 - Understanding .NET Assemblies

public static void Main()

Chapter 10 - Processes, AppDomains, Contexts, and Threads

{

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

// Assume the Cars type has an indexer method.

Part Four - Leveraging the .NET Libraries

Cars carLot = new Cars();

Chapter 12 - Object Serialization and the .NET Remoting Layer

// Make some cars and add them to the car lot.

Chapter 13 - Building a Better Window (Introducing Windows Forms) carLot[0] = new Car("FeeFee", 200, 0);

Chapter 14 - A Better Painting Framework (GDI+)

carLot[1] = new Car("Clunker", 90, 0);

Chapter 15 - Programming with Windows Forms Controls carLot[2] = new Car("Zippy", 30, 0);

Chapter 16 - The System.IO Namespace

// Now obtain and display each item.

Chapter 17 - Data Access with ADO.NET

for(int = 0; i < 3; i++)

Part Five - Web{Applications and XML Web Services

Chapter 18 - ASP.NET ConsoleWeb Pag s.WriteLine("Carand b Controls number {0} :", i);

Chapter 19 - ASP.NET WebConsoleApplications.WriteLine("Name: {0} ", carLot[i].PetName);

Chapter 20 - XML WebConsoleServices .WriteLine("Max speed: {0} ", carLot[i].MaxSpeed);

Index

}

List of Figures}

 

List} of Tables

 

As you can see, indexers behave much like a custom collection supporting the IEnumerator and IEnumerable interfaces. The only major difference is that rather than accessing the contents using interface references, you are able to manipulate the internal collection of automobiles just like a standard array.

Now for the big question: How do you configure the Cars class (or any class) to do so? The indexer itself is represented as a slightly mangled C# property. In its simplest form, an indexer is created using the this[] syntax:

// Add the indexer to the existing class definition.

public class Cars : IEnumerable

{

...

// To contain the car types.

private ArrayList carArray = new ArrayList();

C# and the .NET Platform, Second Edition

// The indexer returns a Car based on a numerical index.

by Andrew Troelsen ISBN:1590590554

public Car this[int pos]

{

Apress © 2003 (1200 pages)

This comprehensive text starts with a brief overview of the

 

 

// Accessor returns an item in the array.

 

C# language and then quickly moves to key technical and

 

get

 

architectural issues for .NET developers.

 

{

 

if(pos < 0)

throw new IndexOutOfRangeException("Out of range!");

Table of Contents

else

C# and the .NET Platform, Second Edition

return (Car)carArray[pos];

Introduction

}

Part One - Introducing C# and the .NET Platform

// Or simply call carArray.Add(value);

Chapter 1 - The Philosophy of .NET

set {carArray.Insert(pos, value);}

Chapter 2 - Building C# Applications

}

Part Two - The C# Programming Language

}

Chapter 3 - C# Language Fundamentals

Chapter 4 - Object-Oriented Programming with C#

ChapterBeyond5the- useExceptionsof the "this"and Objectkeyword,Lifetimethe indexer looks just like any other C# property declaration. Do be Chapteraware that6 -indexersInterfacesdoanotd Collectionsprovide any array-like functionality beyond the use of the subscript operator. In

other words, the object user cannot write code such as the following:

Chapter 7 - Callback Interfaces, Delegates, and Events

Chapter 8 - Advanced C# Type Construction Techniques

Part// ThrUsee -SystemProgramming.Arraywith.Length?.NET AssembliNope!s

ChapterConsole9 .-WriteLine("CarsUndersta ding .NET Assembliesin stock: {0} ", carLot.Length);

Chapter 10 - Processes, AppDomains, Contexts, and Threads

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

To support this functionality, you would need to add your own Length property to the Cars type, and

Part Four - Leveraging the .NET Libraries

delegate accordingly:

Chapter 12 - Object Serialization and the .NET Remoting Layer

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

public class Cars

Chapter 14 - A Better Painting Framework (GDI+)

{

Chapter 15 - Programming with Windows Forms Controls

...

Chapter 16 - The System.IO Namespace

// Containment/delegation in action once again.

Chapter 17 - Data Access with ADO.NET

public int Length() { carArray.Count; }

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

At this point you have equipped a class to support an indexer method. As you can gather, this technique is Indexyet another form of syntactic sugar given that the semantics of a type indexer can also be represented by

Lisimplet of Figurespublic methods. For example, if the Cars type did not support an indexer, we would be able to allow

ListtheofoutsideTables world to interact with the internal array list using a named property or traditional accessor/mutator methods. Nevertheless, you will find that indexers can help make the manipulation of your types more natural. Also be aware that many key technologies within the .NET base class libraries (ADO.NET, ASP.NET, and so forth) already have numerous types that support array-like manipulations.

SOURCE The Indexer project is located under the Chapter 8 subdirectory.

CODE

A VariationC#ofandthetheCars.NET Platform,IndexerSecond Edition

by Andrew Troelsen

ISBN:1590590554

The current Cars type defined an indexer that allowed the caller to identify the subitem it is interested in

Apress © 2003 (1200 pages)

obtaining using a numerical index. Understand, however, that this is not a requirement of a type indexer.

This comprehensive text starts with a brief overview of the

For example, assumeC# languageyou wouldandratherthen quicklycontainmovesthe Carto keyobjectstechnicalwithinanda System.Collectionsarchitectural.Specializedissues.ListDictionary,for .NET developersrather than. an ArrayList. Given that ListDictionary types allow access to the contained types using a key token (such as a string), it could configure the Cars indexer as follows:

Table of Contents

C# and the .NET Platform, Second Edition

public class Cars

Introduction

Part One - Introducing C# and the .NET Platform

{

Chapter 1 - The Philosophy of .NET

// This class maintains a dictionary of cars.

Chapter 2 - Building C# Applications

private ListDictionary carDictionary;

Part Two - The C# Programming Language

public Cars(){ carDictionary = new ListDictionary(); }

Chapter 3 - C# Language Fundamentals

// The new

indexer.

public Car

this[string name]

Chapter 4

- Object-Oriented Prog amming with C#

Chapter 5

- Exceptions and Object Lifetime

{

returnand Collections(Car)carDictionary[name]; }

Chapter 6

- Interfacesget {

Chapter 7

- Callbackset {Interfaces,carDictionaryDelegates,.Add(name,and Events value); }

}

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

The caller would now be able to interact with the internal cars as shown here:

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

Part Four - Leveraging the .NET Libraries

public class CarApp

Chapter 12 - Object Serialization and the .NET Remoting Layer

Chapter{

13

- Building a Better Window (Introducing Windows Forms)

Chapter public14 - A BetterstaticPaintingvoidFrameworkMain()(GDI+)

 

{

- Programming with Windows Forms Controls

Chapter 15

Chapter 16

 

Cars carLot = new Cars();

- The System.IO Namespace

Chapter 17

 

// Add to car dictionary.

- Data Access with ADO.NET

 

 

 

carLot["FeeFee"] = new Car("FeeFee", 200, 0);

Part Five - Web Applications and XML Web Services

 

 

 

carLot["Clunker"] = new Car("Clunker", 90, 0);

Chapter 18

- ASP.NET Web Pages and Web Controls

 

 

 

carLot["Zippy"] = new Car("Zippy", 30, 0);

Chapter 19

- ASP.NET Web Applications

 

 

 

// Now get Zippy.

Chapter 20

- XML Web Services

 

 

 

Console.WriteLine("***** Getting Zippy using indexer *****");

Index

 

 

Car zippy = carLot["Zippy"];

 

 

 

List of Figures

Console.WriteLine("{0}'s max speed is {1} MPH",

List of Tables

zippy.PetName, zippy.MaxSpeed);

}

}

 

 

 

 

 

SOURCE The DictionaryIndexer project is located under the Chapter 8 subdirectory.

CODE

Indexers: Further Details

Also understand that indexers, like any member, may be overloaded. Thus, if it made sense to allow the caller to access subitems using a numerical index or a string value, you might define multiple indexers for a single type (as you will see, this is a very common technique used within the ADO.NET class library).

string this[int index] { get; set; }
// This interface defines an indexer that returns

Furthermore, if you want to get really exotic, you can also create an indexer that takes multiple

C# and the .NET Platform, Second Edition

parameters. Assume you have a custom collection that stores subitems in a two-dimensional array. If this

by Andrew Troelsen ISBN:1590590554 is the case, you may configure an indexer method as follows:

Apress © 2003 (1200 pages)

This comprehensive text starts with a brief overview of the

public class SomeContainer

C# language and then quickly moves to key technical and

{architectural issues for .NET developers.

private int[,] my2DintArray = new int[10, 10]; public int this[int row, int column]

Table of {Contents/* get or set value from 2D array */ }

}

C# and the .NET Platform, Second Edition Introduction

Part One - Introducing C# and the .NET Platform

Finally, understand that indexers can be defined on a given .NET interface type to allow implementing

Chapter 1 - The Philosophy of .NET

types to provide a custom implementation. Such an interface is seen here:

Chapter 2 - Building C# Applications

Part Two - The C# Programming Language

public interface IAmAnInterfaceWithAnIndexer

Chapter 3 - C# Language Fundamentals

{

Chapter 4 - Object-Oriented Programming with C#

Chapter 5 - Exceptions and Object Lifetime

// strings based on a numerical index.

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

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