100% found this document useful (2 votes)
9 views

C Class Design Handbook Coding Effective Classes 1st Edition Richard Conway download

The C# Class Design Handbook provides a comprehensive overview of class design in .NET, detailing the structure and components of types, including type members such as methods, properties, and events. The book covers essential topics like inheritance, polymorphism, and code organization, making it a valuable resource for developers looking to enhance their understanding of C# class design. It includes practical examples and guidelines to effectively utilize C# features for robust software development.

Uploaded by

buzasvinci6u
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
9 views

C Class Design Handbook Coding Effective Classes 1st Edition Richard Conway download

The C# Class Design Handbook provides a comprehensive overview of class design in .NET, detailing the structure and components of types, including type members such as methods, properties, and events. The book covers essential topics like inheritance, polymorphism, and code organization, making it a valuable resource for developers looking to enhance their understanding of C# class design. It includes practical examples and guidelines to effectively utilize C# features for robust software development.

Uploaded by

buzasvinci6u
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

C Class Design Handbook Coding Effective Classes

1st Edition Richard Conway download

https://ebookgate.com/product/c-class-design-handbook-coding-
effective-classes-1st-edition-richard-conway/

Get Instant Ebook Downloads – Browse at https://ebookgate.com


Get Your Digital Files Instantly: PDF, ePub, MOBI and More
Quick Digital Downloads: PDF, ePub, MOBI and Other Formats

Combinatorial matrix classes 1st Edition Richard A.


Brualdi

https://ebookgate.com/product/combinatorial-matrix-classes-1st-
edition-richard-a-brualdi/

Solutions Microelectronic Circuit Design 3rd edition


Richard C. Jaeger

https://ebookgate.com/product/solutions-microelectronic-circuit-
design-3rd-edition-richard-c-jaeger/

Adaptive Code via C Agile coding with design patterns


and SOLID principles 1st Edition Gary Mclean Hall

https://ebookgate.com/product/adaptive-code-via-c-agile-coding-
with-design-patterns-and-solid-principles-1st-edition-gary-
mclean-hall/

Fast and Effective Embedded Systems Design 1st Edition


Rob Toulson

https://ebookgate.com/product/fast-and-effective-embedded-
systems-design-1st-edition-rob-toulson/
Effective C 50 Specific Ways to Improve Your C 1st
Edition Bill Wagner

https://ebookgate.com/product/effective-c-50-specific-ways-to-
improve-your-c-1st-edition-bill-wagner/

Designing Interfaces Patterns for Effective Interaction


Design 3rd Edition Tidwell

https://ebookgate.com/product/designing-interfaces-patterns-for-
effective-interaction-design-3rd-edition-tidwell/

Designing Interfaces Patterns for Effective Interaction


Design 1st edition Edition Jenifer Tidwell

https://ebookgate.com/product/designing-interfaces-patterns-for-
effective-interaction-design-1st-edition-edition-jenifer-tidwell/

Effective Site Investigation Second Edition. Edition C.


R. I. Clayton

https://ebookgate.com/product/effective-site-investigation-
second-edition-edition-c-r-i-clayton/

Product Design and Factory Development The Handbook of


Manufacturing Engineering Second Edition Volume 1
Richard Crowson

https://ebookgate.com/product/product-design-and-factory-
development-the-handbook-of-manufacturing-engineering-second-
edition-volume-1-richard-crowson/
C# Class Design Handbook:
Coding Effective Classes
This book takes a top-down look at what exactly makes up a class in .NET. It
begins by defining a type and how classes relate to the .NET type framework.
It then examines what makes up types: type members. The majority of the book
is devoted to looking at the different mechanisms C# provides for defining type
members (methods, constructors, properties, operators, and events) and
examining how types combine to make up assemblies.

Summary of Contents
Introduction
Chapter 1: Defining Types
Chapter 2: Type Members
Chapter 3: Methods
Chapter 4: Properties and Operators
Chapter 5: Constructors and the Object Lifecycle
Chapter 6: Events and Delegates
Chapter 7: Inheritance and Polymorphism
Chapter 8: Code Organization and Metadata
Appendix A: Support, Errata, and Code Download
Index
C# Class Design Handbook:
Coding Effective Classes

Richard Conway
Teun Duynstee
Ben Hyrman
Roger Rowland
James Speer of Charteris pIc

APress Media, LLC


C# Class Design Handbook:
Coding Effective Classes

Copyright © Apress 2003

A l l rights r e s e r v e d . N o p a r t o f this w o r k m a y b e r e p r o d u c e d o r t r a n s m i t t e d i n a n y f o r m
or b y a n y means, electronic o r mechanical, i n c l u d i n g p h o t o c o p y i n g , recording, o r b y
a n y i n f o r m a t i o n storage o r r e t r i e v a l system, w i t h o u t t h e p r i o r w r i t t e n p e r m i s s i o n o f t h e
copyright o w n e r a n d the publisher.

ISBN 978-1-59059-257-1 ISBN 978-1-4302-1124-2 (eBook)


DOI 10.1007/978-1-4302-1124-2

T r a d e m a r k e d n a m e s m a y a p p e a r i n this b o o k . Rather t h a n u s e a t r a d e m a r k s y m b o l
w i t h every occurrence o f a trademarked name, w e use the names o n l y i n a n editorial
fashion a n d t o the benefit o f the trademark owner, w i t h n o intention o f infringement o f
the trademark.

T h e i n f o r m a t i o n i n this b o o k is d i s t r i b u t e d o n a n "as i s " basis, w i t h o u t w a r r a n t y .


A l t h o u g h every p r e c a u t i o n has b e e n t a k e n i n the preparation o f this w o r k , neither t h e
a u t h o r s ) n o r A p r e s s s h a l l h a v e a n y l i a b i l i t y t o a n y p e r s o n o r e n t i t y w i t h respect t o a n y
loss o r d a m a g e c a u s e d o r a l l e g e d t o b e c a u s e d d i r e c t l y o r i n d i r e c t l y b y t h e i n f o r m a t i o n
c o n t a i n e d i n this w o r k .

T h e s o u r c e c o d e f o r this b o o k is a v a i l a b l e t o readers at http://www.apress.com i n t h e


D o w n l o a d s section.

S o m e m a t e r i a l w a s first p u b l i s h e d i n a d i f f e r e n t f o r m i n Visual Basic .NET Class Design


Handbook (1-86100-708-6), M a y 2002.
Credits

Editorial Board Additional Editing


Dan Appleman Andrew Polshaw
Craig Berry
Gary Cornell Technical Reviewers
Tony Davis Andrew Krawczyk
Steven Rycroft Roger Rowland
Julian Skinner
Martin Streicher Managing Editor
Jim Sumser Emma Batch
Karen Watterson
Gavin Wright Index
John Zukowski Michael Brinkman

Additional Material Project Manager


Damon Allison Beckie Stones
Andy Olsen
Steven Sartain Production Coordinator
Sarah Hall
Commissioning Editor
James Hart Proof Reader
Chris Smith
Technical Editors
Faterna Beheranwala Cover
Nilesh Parmar Natalie O'Donnell
About the Authors
Richard Conway
Richard Conway started programming BASIC with
the ZX81 at an early age later graduating to using
BASIC and 6502 assembly language, COMAL, and
Pascal for the BBC B and Archimedes RISC
machines. He is an independent software
consultant who lives and works in London. He
has been using Microsoft technologies for many
years and has architected and built enterprise
systems for the likes of IBM, Merrill Lynch, and
Reuters. He has focused his development on
\Xtindows DNA including various tools and
languages such as COM+, VB, XML, C++, J++,
BizTalk, and more recently, Data Warehousing.
He has been actively involved in EAP trials with
Microsoft for .NET My Services and the .NET
Compact Framework. He has spent the last two
and a half years since the release of the technical
preview (of VS.NET) programming proof-of-
concept and enterprise system projects in C#. His
special area of interest is Network Security and
Cryptography. Richard is a contributor to both C#
Today and ASP Today. He is currently involved in
a product development and consultancy alliance -
http://Www.vertexion.co.uk - specializing in data
warehousing and security products.

He can be contacted at
richard [email protected].

leun Duynstee
Teun Duynstee lives in the Netherlands. He works
with Macaw as a lead software developer and
loves programming, his girlfriend Marjolein, and
Arnie the cat.
Ben Hyrman
Ben works as a Program Architect for Best Buy, in
tropical Minneapolis, Minnesota. Ben enjoys the
balmy Minnesota weather with his loving wife,
Dawn, and an overactive mutt of a dog, Bandit.
When they're not busy with work or off on road
trips, Ben and Dawn enjoy painting their house
and arguing over database design patterns.

I would like to thank Damon Allison


for being my sounding board for all
of my crazy ideas. I'd also like to
thank Richard Scott, because he's
British and he asked me to. Lastly,
I'd like to thank Wrox for this
excellent opportunity.

Roger Rowland
Roger Rowland is a freelance IT Consultant based
in the UK. He has 25 years of software
development experience on a variety of platforms,
and is a regular contributor to the Wrox C# Today
web site. He currently specializes in Microsoft
technologies including YC++, VB, C#, SQL, and
ASP. Roger is a member of the Institution of
Analysts and Programmers, a professional member
of the British Computer Society, and a member of
the IEEE Computer Society. He holds a Masters
Degree in computing and is currently undertaking
a part-time PhD at the University of East Anglia
researching into medical imaging and computer
assisted surgery. Research techniques include 3D
graphics and volume rendering using OpenGL,
and he has published a number of academic
papers. Married, with two children and always
incredibly busy, Roger may nevertheless be
contacted at [email protected].
James Speer of Charteris pic
James has been a software developer since 1987,
beginning his career programming in BCPL and
C++. He currently specializes in distributed .NET
component development, particularly - C#, .NET
Remoting, Serviced Components and MSMQ.
James is currently employed by Charteris pic
(www.charteris.com) as a Senior Developer and can
be reached at [email protected].

Thanks to Mom and Dad for the


Acorn Electron andJune for lending
me your Vic 20.
C#"
Table of Contents

Introduction 1
Who Is This Book For? 2
What Does This Book Cover? 2
What Doesn't It Cover? 2
What Will You Learn? 3
What Do You Need? 4

Chapter 1: Defining Types 7


Types 8
The .NET Type System 9
The Common Type System (CTS) 9
The Common Language Specification (CLS) 10
Value Types and Reference Types 11
Value Types and the Stack 11
Reference Types and the Managed Heap 12
Value Types and the Managed Heap 14
Understanding .NET Memory Usage 14

Value Types 15
Primitive Types 16
Viewing the Output from the Compiler 19
User-Defined Value Types (Structures) 22
Defining and Using Value Types 23
Using Inheritance with Value Types 25
Enumerations 28
Enumerated Types 28
Bit Rags 30
Inside an Enumerated Type 32

Reference Types 33
Class Types 34
Defining Classes in C# 34
Defining Accessibility for Classes 37
Nested Classes 38
Creating and Disposing of Class Objects 40
Table of Contents

Delegates 41
Arrays 42
Declaring Arrays 42
Initializing Array Elements 42
Using Arrays 43
Casting Arrays 44
Strings 45
Declaring Strings 45
Strings are Immutable 45
Using Strings 46

Using Value Types as Reference Types 48


Boxing and Unboxing 48
Value Types as Objects 48
Performance Implications 49
Other Boxing Scenarios 50

Interfaces 51
Summary 52

Chapter 2: Type Members 55


Constants 56
Not-so Constants 60

Fields 62
Properties 64
Methods 67
Method Overloading 67
Properties versus Methods 68
Static Type Members 69
Events and Delegates 72
Operators 73
Constructors 73
Destructors 74
Working with System.ObJect 75
GetTypeO 75
ToStringO 76
EqualsO 78
GetHashCodeO 80
EqualsO and GetHashCodeO 81
Summary 82

ii
Table of Contents

Chapter 3: Methods 85
Invoking Methods 85
Method Scope and Visibility 87
Method Types 87
Instance and Static Method Example 88
Instance and Static Method Best Practice 89
Arguments and Parameterized Methods 90
Parameter Types 90
Passing by Value 90
Passing by Reference 91
Output Parameters 93
Passing Reference Types versus Value Types 95
Passing Value Types by Value 96
Passing Value Types by Reference 98
Passing Reference Types by Value 99
Passing Reference Types by Reference 102
Variable Length Parameter Lists 103
Passing Strings - Immutable Objects 105
Passing Arrays and Upper Bound Checking 106
Passing Enumerated Values 106
Method Overloading 106
Exception Handling 110
What Is an Exception? 111
Try ...Catch ... Finally 112
Throwing Your Own Exceptions 113
Methods and MSIL Code 117
Design Summary 123

Chapter 4: Properties and Operators 1.25


Properties In C# 125
C# Property Syntax 126
Scalar Properties 127
Compiling Scalar Properties into MSIL 129
Read/Write, Read-Only, and Write-Only Properties 131
Static Properties 134
Guidelines for Writing Get Procedures 135
Guidelines for Writing Set Procedures 136
Complete Example of Scalar Properties 136
Indexers 140
Defining a Single Indexer in a Class 141
Compiling Indexers into MSIL 145
Using Indexers with ArrayLists 146
Overloading Indexers 148
Indexer Summary 150

iii
Table of Contents

Operators In C# 151
Operators are in Fact Expressions 151
Operator Overloading Syntax 152
Operators and Classes 154
Compiling Operators into MSIL 157
Operator Overload and Cross-Language Support 159
Symmetrical Operator Overloads 160
Type Comparison and Equality 161
Operators and Structures 166
Operator Overloading in Pairs 169
Operator Overload Best Practice 171
Operators Summary 171
Summary 172

Chapter 5: Constructors and the Object Lifecycle 175


Object Creation 178
Destroying Objects 181
Using Constructors 186
Chaining Constructors 187
Calling a Base Class Constructor 188
Private Constructors 189
Static Constructors 191
Conversion Operators 193
Cloning Objects 196
Using the Copy Constructor 196
The ICloneable Interface 198
Serialization and Deserlallzatlon 200
Design Patterns 204
Singleton 204
The Abstract Factory Pattern 207
Lazy Initialization 210
Copy-On-Write 211
Summary 212

Chapter 6: Events and Delegates 215


Delegates 216
Creating and Using Simple Delegates 217
Creating and Using Multicast Delegates 223
Creating and Using Asynchronous Delegates 231
Events 238
Event Architecture 239

iv
Table of Contents

Publishing and Subscribing to Events 241


Publishing our Event 241
Registering to a Published Event 244
Raising the Event 246
Creating Events that Pass Information 248
Defining Static Events 251
Dynamically Registering and Unregistering 253
Defining your own Registration Methods 254
Role of Events in the Type Interfaces of the .NET Framework 256
Summary 258

Chapter 7: Inheritance and Polymorphism 261


Inheritance 262
Inheritance Hierarchies 264
Overriding Base Class Operations 265
Abstract Classes and Interfaces 266
Types of Inheritance 267
Multiple Inheritance 268
Creating a Class Hierarchy 270
Class Definitions 271
Designing a Base Class 272
Deriving Classes 277
Polymorphism in Action 280

Interface-Based Programming 284


Defining an Interface 285
Implementing the Interface 285
Polymorphism with Interfaces 286
Multiple Interface Inheritance 288
Interfaces in IL 289
Scoping Interface Methods 291
Casting to Different Interface Types 293
Name Ambiguity and Shadowing 294
Summary 294

Chapter 8: Code Organization and Metadata 297


Structuring Applications with Namespaces 298
Designing and Implementing Namespaces 301
Example of Designing Namespaces 301
Example of Implementing Namespaces 302
Nested Namespaces 312

Understanding Assemblies 315


What Is An Assembly? 315
Single-File Assemblies 315
Multi·File Assemblies 316
Logical vs. Physical Organization 316

v
Table of Contents

Metadata 316
Viewing Metadata in a Single-File Assembly 317
Creating Multi-File Assemblies 322

Deploying Applications as Assemblies 327


Deploying Single-Assembly Applications 328
Deploying Applications using Private Assemblies 329
Deploying Private Assemblies in the Same Folder 329
Deploying Private Assemblies in a Different Sub-Folder 331
Deploying Shared Assemblies 333
Creating a Shared Assembly as a Strongly Named Assembly 335
Creating an Application that Uses the Shared Assembly 337
Installing Shared Assemblies into the Global Assembly Cache 339

Generating Documentation for an Assembly 340


Using Assembly-level Attributes 341
XML Documentation 343
Summary 347

Appendix A: Support. Errata. and Code Download 349


How to Download the Sample Code for the Book 349
Errata 350
forums.apress.com 350

Index 353

vi
Table of Contents

vii
C#"
Introduction
C# is a language that follows in a grand tradition of programming language design; it
draws its influences from C++ and Java, and even Delphi and Visual Basic - a rich
inheritance, which provides it with much that is familiar to many developers, but also
much that is alien or unexpected.

Programmers unfamiliar with object-oriented, C-family, 'curly-bracket' languages,


perhaps coming to C# from a background with Visual Basic 6 or ASP VBScript, often
find the scope of the object-oriented features in C# daunting. Those coming from other
object-oriented platforms - C++ or Java for example - find some of C#'s additional
facilities surprising or confusing, while other, seemingly familiar syntaxes can behave in
curiously different ways.

This book takes the lid off C#'s object-oriented model, and examines how we use C#
as a language for creating classes (and, indeed, other kinds of types). Since everything
we code in C# is a type, all our logic belongs to methods of types, and the state of our
program at any moment is tied up in the values stored in the fields of instances of
types in memory. A good understanding of how to create those types is therefore
fundamental to good C# programming.

We'll explore what options C# gives us in declaring types and type members in our
code, and the impact our decisions will have on code that uses our types. We'll see
how we can code differently when our types are for public use, and when types are
for use within our own code. We'll look at what we can do to ensure our types are
only used in ways we design for, and how we can expose functionality from our types
in a consistent, logical, predictable, and user-friendly manner, for other code to exploit.
Introduction

Who Is This Book For?


This book is for C# developers who want to explore the full capabilities of the .NET
platform. If you want to define your own data types, build your own class hierarchies,
and build classes with robust interfaces, then you need a deep understanding of the
mechanisms C# provides for defining classes. That is the subject of this book.

This book assumes you're already coding with C#, you're already familiar with the
basic syntax, and you're regularly writing code that works. You should be familiar with
your chosen development tools and know how to compile and run C# code.

You should be aware of .NET's basic object-orientation mechanisms - for example, that
objects are instances of classes, how objects are instantiated, and how methods and
properties on an object are accessed. We'll recap on the meaning and syntax of most of
C#'s class construction keywords as we discuss them, however.

What Does This Book Cover?


Every time we write code in C#, we're coding a class - it's unavoidable. This book
addresses the decisions we make as programmers in this environment, by placing them
in the context of what they really are: decisions about class design. So, when we write
a method and choose whether to make it static, whether it is to be public or
private, what parameters it should take, and so on, this book helps us look at those
decisions in the context of how they impact on the design of a class.

This book takes a step back from the code we write every day and asks, "What is it really
doing?" It asks you not to consider each C# keyword or syntax construction just in terms of
its effect, but to consider how it accomplishes that effect. In the course of this book, we'll
see how all our code is compiled into .NET types; how we defme type members; how type
members are inherited; how types are aggregated into assemblies; how we can control the
creation of instances of types; and many more aspects of effective class coding.

What Doesn1t It Cover?


This isn't a book about object-oriented analysis and deSign, UML modeling, or design
patterns - although we'll encounter all of these along the way, for detailed tutorials in
these tools you should look elsewhere. It doesn't address the question of how to take a
business problem, and decide which classes you should code to solve it. Instead, it
focuses on the questions of implementation: how you can code a class that provides a
particular kind of behavior.

2
What Will You Learn?

It also isn't a fundamental introduction to object-orientation, although any C#


programmer should already be familiar with the idea of having an instance of an
object, and calling methods on it and accessing properties, even if not with the process
of defining your own types. If you're comfortable using objects, then this book will not
assume more than you know.

What Will You Learn?


The book takes a top-down look at what exactly makes up a class in .NET. We begin
by describing what a type is, and how classes relate to the .NET type framework. Then
we examine what makes up types: type members. We devote the majority of the book
to looking at the different mechanisms C# provides for defining type members
(methods, constructors, properties, operators, and events), and finally examine how
types go together to make up assemblies.

Chapter by chapter, here'S what to expect:

o Chapter 1 - Defining Types


This chapter explains what exactly a type is, what role types play in .NET,
and what kinds of types exist. We also examine the different types we can
declare in C# and how they map to .NET types.
o Chapter 2 - Type Members
In the second chapter, we examine type members: what they are, how we
can define them, and how we can modify them using C# keywords. We
also examine the type members inherited by every type from the .NET root
class, System.Object.
o Chapter 3 - Methods
Methods are the workhorse of .NET applications; they contain all our
program logic. This chapter examines the behavior common to all methods,
and how simple methods are defined in C#. We look at how parameters
are passed to methods, and how methods return values, or throw
exceptions, to communicate back to the code that called them.
o Chapter 4 - Properties and Operators
Properties (both scalar and indexed) are a mechanism allowing us to create
specialized methods for accessing data belonging to our type. Operators are
specialized methods that allow consumers of our types to combine them
using convenient operator-based syntax. This chapter examines how
properties are implemented, how indexed properties work, and the
creation and use of operators.

3
Introduction

Q Chapter 5 - Constructors and the Object Ufecycle


Constructors are special methods that are called to initialize new instances of
a type. In this chapter, we see how these special methods are coded, and
how we can use them to control what code can create instances of a type.
We'll also examine object cloning, conversion operators, and some common
coding techniques for controlling the creation of instances of our classes.
Q Chapter 6 - Events and Delegates
The most complex type member in C# is the Event, and the most complex
of C#'s types is the delegate. Events are based on delegates, and the
combination of the two can be quite daunting for programmers. This
chapter explains how delegates work, and then how .NET provides its
event infrastructure through delegate fields and specialized methods.
Q Chapter 7 - Inheritance and Polymorphism
A type is more than the sum of its members; it also has all the members it
inherits from its superclass as well. This chapter explains how .NET type
inheritance works, when members are and aren't inherited, and how we
can control and exploit it using C#. We also look at the role and use of
interfaces and abstract classes.
Q Chapter 8 - Code Organization and Metadata
When we code a class in C#, we have to make some decisions about where
exactly to put it, both logically within a names pace structure, and
physically, within a source file, and ultimately, within a .NET assembly. This
chapter discusses these issues. We also see how to add data to our classes
that may be of use to other code that makes use of them, using .NET
metadata, and how to document our classes to provide information for
other programmers about how they are used.

What Do You Need?


To make use of this book, you need to be able to compile and execute code written in
C#. This means you will require either:

Q The .NET Framework SDK obtainable from Microsoft's MSDN site


(http://msdn.microsoft.com), in the Software Development Kits category. The
download page at time of publication could be reached via the following URi:

http://msdn.microsoft.com/downloadS/sample.asp?
uri =/msdn-fileS/027/000/976/msdncompositedoc.xml

Q A version of Visual Studio .NET that incorporates Visual C# .NET. The 2002
edition of the Visual C# .NET IDE is included with the following
Microsoft products:
• Microsoft Visual C# .NET Standard
• Microsoft Visual Studio .NET Enterprise Architect

4
What Do You Need?

• Microsoft Visual Studio .NET Enterprise Developer


• Microsoft Visual Studio .NET Professional
The product homepage is at http://msdn.microsoft.com/vstudio/.

There are several .NET implementations for other platforms undelWay, and support for
C# compilation on Linux, UNIX, and Windows is provided by the Mono project
(http://www.go-mono.com/).MonocodedoesnothaveaccesstothefullMicrosoft.NET
class library, but follows the same syntactic rules as Microsoft's C#, meaning the lessons
in this book should apply in equal measure.

5
C#"
Defining Types
C# is an object-oriented programming language, and one of the principles which guide
its design is type safety. During object-oriented analysis and deSign, we identify the most
important objects in our system, and consider how they will relate to each other. When
we program in C#, classes are the main mechanism we use to define the behavior of the
objects that will exist in our program at run time. However, C# offers us a great many
ways to package up the code that defines our application - and not just in classes.

Whenever we code in C#, though, what we write are always types, and these types
represent a combination of behavior and data storage requirements. When the program
runs, it creates instances of types (which allocate the data storage required), and makes
available the features of the types. Within the .NET environment, type-safe code only
accesses the memory locations it is authorized to access and types interact only in
well-defined, permitted ways. This is important for producing secure, stable applications
that ensure even badly written code can't do too much damage, and plays by the rules.

This book aims to help C# developers gain a deeper and more confident under:standing
of how to build well designed classes that will behave correctly and consistently within
the .NET Framework. Through exploration and examples, we will give you an
awareness of the consequences of decisions made during the design and development
phases, and will point out any not-so-obvious similarities with or differences from other
object-oriented languages like C++ and Java.

We'll begin this book by looking at what exactly a type is. In this chapter, we'll
examine .NET's type system, and the kinds of type available to us as developers.
Chapter 1: Defining Types

Types
In programming, we use the term 'type' to describe a particular kind of value. For
example, C++ and Java programmers will be familiar with types such as int, float,
and double. For each type, the compiler knows the following information:

o How much memory to allocate when we create a value of this type


o What operations are allowed to be performed using this value

The concept of types is fundamental to strongly typed programming languages,


including all .NET languages. In a strongly typed language, the type of value stored in
each variable is known at compile time, so the compiler can predict how we intend to
use each variable, and can therefore tell us when we are going wrong.

A type is a contract. A variable of a particular type guarantees contractually that it will


contain all the data you would expect a value of the given type to have, and it can be
processed in all the ways we would expect a value of that type to be processed. We
sometimes call the contract of a type its interface.

C++ Note: Having been used to defining the interfaces ofyour c++ classes
in header files, you will already be aware that C# has no headerfiles. The
definition of c# types is included in the compiled assembly as metadata.
You should also remember that the C# compiler does not worry about the
order of type declarations in your source code.

To a computer all data is just chains of ones and zeroes. When we have a variable in
our program, ultimately that variable is simply holding a binary number of some kind.
So, when we ask the computer to display that variable on the screen, perform a
calculation on it, or retrieve one of the variable's properties, the computer needs to
know what type the variable contains in order to know how to interpret its value, and
thus respond to our request. For example, an integer and a single-precision floating-
point number can both be stored in four bytes of binary data. Take the following four
bytes, for example:

00110110 11011011 10001010 01110100

If the value were interpreted as an integer, it would represent the number 920,357,492.
Interpreted as a single-precision floating-point value, it has the approximate value of
6.5428267E-6. So, if a variable contains this binary number, and we ask .NET to add
one to it, the result is going to depend not only on what value is in the variable, but
also on the variable type.

A type describes the purpose of any string of ones and zeroes in memory. It enables us
to compare values of two integers and see if one is greater than another, retrieve a
string representing a value, or modify the value in a particular way.

8
Types

The .NET Type System


The .NET Framework includes a large selection of types that assists software
development in the .NET languages. All types we define and use in our own code must
conform to the .NET Framework standards to ensure that they operate correctly in the
runtime environment. There are two important specifications that define these
standards, the Common Type System (crS) and the Common Language
Specification (CLS).

The Common Type System (CTS)


The Common Type System shows compiler writers how to declare and use types used in
the .NET runtime. It defines rules that all .NET languages must follow in order to produce
compiled code that can run within the Common Language Runtime (CLR). The CTS
provides an object-oriented framework within which individual .NET languages operate.
The existence of this common framework is crucial for ensuring type-safety and security at
run-time, and also facilitating cross-language integration. In essence, the Common Type
System is the backbone of the .NET Framework.

Figure 1 shows how the Common Type System is organized:

Figure 1

Interfaces Value Types Reference Types

J ! classes I
struct~ ~xedvalue~

Enumeratio~ '--_ _Ar_ra~


~egates

The diagram shows how the Common Type System makes a clear distinction between
value types and reference types, which are discussed below. It also allows us to define
pure interfaces; an interface is a simple definition of a contract, which is then implemented
by another type (or types) - it separates out the defmition of a contract from the
implementation of that contract. All of the other types combine the above two things.

c++ Note: Intetfaces are akin to pure abstract classes. Unlike in C++, a C#
class may only inherit from a single base class. However, a C# class may
additionally inherit from multiple intetfaces.

9
Chapter 1: Defining Types

Java Note: Like java, C# supports single inheritance of classes but


mUltiple inheritance of interfaces. Unlike java-however, C# allows explicit
implementation of interfaces, which avoids problems with naming
conflicts. We'll see this in action later.

The Common language Specification (ClS)


While the crs defines how types are created and managed within the runtime, the
Common Language Specification is more concerned with language interoperability. The
CLS describes a minimum set of features that must be supported by any compiler
targeting the .NET runtime. While we're primarily C# developers, it is important to
understand the significance of .NET's language independence.

The CLS makes it extremely easy to use several different programming languages in the
same application. Whenever we compile source code written in a CLS-compliant
language, it is compiled into a standard .NET Framework byte code format called
Microsoft Intermediate Language (MSIL). The CLS ensures that certain types and
language constructs are all compiled to the same MSIL equivalents whatever the
language used. This means we can easily mix-and-match C#, Visual Basic .NET,
Managed Extensions for C++, Visual J#, or JScript .NET within the same application,
provided we only use CLS compliant types in any public interfaces declared in our
code. To ensure this, the C# compiler can be instructed to check the code and issue
warnings if we break any rules.

The use of an intermediate byte code format will be familiar to Java developers. Just as
Java is typically compiled to byte code before being run in a managed environment
(the Java Virtual Machine), so are C# and other .NET languages compiled to MSIL
before being run by the .NET Common Language Runtime (CLR). One difference is that
Java optionally allows the byte code to be interpreted at run time rather than compiled
to native code, while MSIL is always compiled, either by the Just In Time compiler
(JIT), or as a pre-JITted assembly loaded from the Global Assembly Cache (GAC). The
other important difference is that the language-neutral nature of MSIL was designed
into the .NET Framework from day one. As mentioned earlier, the CLS effectively
specifies a set of rules that define how different languages should compile to MSIL and
this facilitates language interoperability.

We need to make an important distinction here. We have a tendency to assume that


the C# language is so closely tied to the .NET runtime that CLS compliance is an
inherent property of the language. Actually C# is a type-safe, feature-rich,
object-oriented language in its own right, and it's perfectly capable of writing code
which is not CLS-compliant. It has primitive types that are not part of the crs, for
example. In this book, while we will predominantly be talking about the .NET type
system, we will also talk about the way the C# compiler targets the .NET runtime when
it compiles your source code. We'll see, for example, how some of C#'s non-CLS
features are exposed to other CLS-compliant languages.

10
Types

It is also worth pointing out here that language interoperability is not just a girrunick. The
CTS and .NET runtime together support many more features than the subset defmed by
the CLS. Different languages expose different, larger subsets of these features, though at
times they overlap. So it is possible that a particular language may be more suitable for
certain parts of an application. As all languages share the common ground defined by the
CLS, we have a guaranteed interface between these languages.

Apart from .NET languages, there are also a number of CLS-compliant languages from
third-party vendors, such as COBOL (Fujitsu), Perl and Python (ActiveState), and
Smalltalk (Quasar Knowledge Systems).

Before we look at the details of value types and reference types, it's useful to know
that all the types in .NET are completely self-describing. This includes things such as
enumerations and interfaces. A compiled .NET assembly (an . exe or a . dll) includes
metadata, in which all the details of the types defined and used by the assembly are
given. For those types defined in the assembly, we can use reflection to interrogate
their definition. This is useful during development, where we don't need header files or
type libraries to identify what properties and methods an object exposes. It is also
crucial at run time, where the CLR uses this information to dynamically resolve method
calls during JIT compilation. This information is stored in a compiled .NET assembly
and is used extensively by the CLR. We'll cover metadata in more detail in Chapter 8.

Value Types and Reference Types


Value types often represent entities that are essentially numerical in nature, such as the date
and time, colors, screen coordinates, and so on. Such entities can be represented by a
simple binary number of a fixed length - the only complication is in interpreting the
meaning of the number. Value types are typically small and exhibit quite simple behaviors,
perhaps just providing an interface for reading and writing the underlying value.

Value Types and the Stack


An example of a simple value type is an eight-byte long integer that can be used to
represent a very large range of dates and times. This number can be interpreted as an offset
of a number of time intervals from a fixed point in time .. NET has a 64 bit DateTirne type
that does just that - it represents the number of ticks (units of 100 nanoseconds, or 10-7
seconds) since 00:00:00 on the first of January, 1 A.D (C.E.), at a particular point in time.
Such values represent different instances in time quite effectively. The type, then, provides
functionality allowing us to extract the year, the month, the day, the hour, minute, second,
and so on, from the simple binary value, in a form that we can make use of.

Since this value type actually consists of very little data, it is easy to pass DateTirne
information around in a program. If we create a variable aDate to hold a DateTirne, it
will need eight bytes of storage exactly. If we create another variable bDate to hold a
DateTirne, it too will take eight bytes of storage. If we now write bDate = aDa te; ,
the eight bytes of data in aDate can be quickly copied and placed into bDate.

11
Chapter 1: Defining Types

When used as local variables or member fields, value types are allocated on the stack.
This is an efficient (but limited size) area of memory used strictly for storing local
variables (variables declared inside method bodies). The effect of the above actions
may be shown schematically as follows. First, we declare two DateTime value types
representing different dates:

DateTime aDate = new DateTime(1994, 08, 28); II 28th August 1994


DateTime bDate = new DateTime(1996, 07, 23); II 23rd July 1996

Then, we copy one date to the other:

aDate " bDate; II copy date

The effect on the running thread's stack is shown in the following diagram. On the left is
the situation immediately before the copy, and on the right is the situation after the copy.

Figure 2

St ck

Value types exhibit copy-by-value semantics; when we copy one value type object to
another, the compiler performs a byte-by-byte copy of our object. Value types are useful
when we don't care how many copies of an object we create; all we care about is the
value. When we pass a value type object into a method, the compiler creates a local copy
of the object. When the method returns, the memory that the local copy of the value type
object was using is automatically reclaimed. This means there are some important
limitations to the kinds of uses to which we can put value types.

Reference Types and the Managed Heap


Since value types have fixed data size, they can be copied quickly and be processed
faster then more complex types, such as arrays. We'll cover arrays in more detail towards
the end of the chapter, but for now, we just need to appreciate that an array is not of a
limited, fixed size. When we create a variable myArray to hold an array of integers, it is
not clear how many bytes of storage it will need - it's going to depend on the size of the
array we put into it. But, when .NET creates a variable, it needs to know how much
space to allocate for it. .NET resolves this issue using a fixed size piece of data called a
reference. The reference value is always the same number of bytes, and refers to a
location in the part of the system memory called the managed heap.

12
Types

The managed heap is a much larger area of memory than the stack but is slower to
access. This is similar to a C runtime heap except that we only use it to allocate
memory; we never specifically free memory from the managed heap. The CLR handles
all of this housekeeping automatically (hence the term managed).

If we create an array of eight integers (which will require 32 bytes of space to store the
array's members), it is created by allocating 32 bytes of the managed heap. When we
place that array into the myArray variable, the location of the array on the managed
heap (a reference to the array) is placed into the variable itself. The myArray variable
that contains this reference is (like all local variables) held on the stack. The memory
pointed to by the reference is on the managed heap.

If we then create another variable myArray2 to hold an array of integers, and then
write myArray2 = myArray;, the value of that reference is copied into myArray2 so
that it points to exactly the same array of integers that myArray did. Arrays, like all
classes, are reference types.

We can see this happening schematically. First, we define two array variables,
initializing one of them to refer to a new instance on the managed heap:

int [) myArray = new int [8);


int [J myArray2;

Then, we'll assign one array to the other. Remember, this only copies the reference:

MyArray2 = myArray;

The result of these operations is shown in the following diagram. On the left, we have
the running thread's stack and the managed heap immediately before the above
assignment; on the right the situation is shown after the assignment. Note that the
reference variables myArray and myArray2 now both refer to the same array instance:

Figure 3

Stack Mana,ed Mana,"


heap heap
rTrfAJray myAJray

I ref J
I
I ref J II
rTrfArray2 1\

I null I

13
Chapter 1: Defining Types

So, reference types represent entities that have a unique identity - they exist in one place
on the managed heap, and are referenced from variables using this identity. When we
defined an integer array and created an instance of this, the CLR allocated memory for
the object and returned us a reference to this new object. When we copied the array into
another variable, we just copied the reference. We still only have a single Array
instance, but there are now two variables referring to it. Reference types exhibit copy-by-
reference semantics. Likewise, when we pass a reference type into a method, the
method receives a copy of the reference to our object, not a copy of its value.

Value Types and the Managed Heap


In a lot of .NET literature, you'll find the generalization 'value types are stored on the
stack'. This is misleading. For example, an array is a reference type, so it is stored on
the managed heap. But if we declare an array containing value-type entities, these
values will be stored inline within the array, so they will actually be stored - as value
types - on the managed heap. When we retrieve one of these values from the array,
we don't get a reference to the location of the value on the heap, we get a copy of the
value from the heap available for local use. The relevant distinction between value and
reference types is that reference types are stored in a unique location on the managed
heap; value types are stored wherever they are used.

Understanding .NET Memory Usage


Right now, Java developers will be thinking that value types are similar to primitive
data types, while reference types are like classes and are heap allocated; C++
developers may be thinking of value types in terms of structs and reference types in
terms of reference variables or pointers to dynamically-allocated memory. This is partly
true in each case, but there are some important points to consider.

Where reference types are concerned, C++ developers will need to get used to not
thinking in terms of pointers. Although this is more-or-less what happens behind the
scenes, the CLR moves objects around on the managed heap and adjusts references on
the fly while the application is running. Since we don't notice this at run time and it's not
obvious from the source code, it confuses matters if you mentally try to translate between
C# and C++ as you write. For example, in C# the syntax for accessing a value type is no
different from that for accessing a reference type. In C++ you might have the following

SomeC14SS *pClassOnHeap = new SomeClass();


pClas50nHeap->DoSomething();
delete pClassOnHeap;

However, in C#, the '->' syntax is only used in unsafe code blocks for backward
compatibility. In normal situations, the ' . ' should be used to access the type's methods
as follows

SomeClass pClassOnHeap = new SomeClass();


pClassOnHeap.DoSomething();
pClassOnHeap = null;

14
Value Types

Note also that we do not explicitly delete the heap-allocated variable when we have
finished with it. We just nullify the reference and leave the rest to the garbage collector.
Once the garbage collector determines that the object is no longer accessible through a
reference stored anywhere else, it will become eligible for disposal. This will be familiar to
Java and Visual Basic developers but may look like sloppy code to a C++ developer. This is
discussed in more detail in Chapter 5 where we'll be looking at the object lifecycle.

InitiaHzing Variables
When a variable of any type is created, it must be initialized with a value before being
accessed. If we forget to put a value into a local variable and then try to use that variable
in a calculation, the C# compiler will give an error. This is very different from C++ where
it is the programmer's responsibility to check for this problem, and from Visual Basic
where local variables are automatically initialized to suitable default values.

The only case in which the C# compiler will initialize variables on your behalf is for
variables declared as fields in a class or struct. This simple compile-time check can
save hours of debugging as it prevents you inadvertently retrieving junk values from
memory left over from other programs.

Everything is an Object
It is important to remember here that any type within the .NET environment, whether a
value or reference type, is an object. This means that every type will inherit explicitly,
implicitly, or indirectly from System.Object. This is similar to the situation in Java,
where there is a single rooted class hierarchy, with every class inheriting in some
manner from java . lang . Obj ect - except that in .NET it also applies to non-
reference types. We'll explore some of the consequences of this throughout the book.

Value Types
There are three main kinds of .NET value types. In this section, we'll discuss each of
these in some depth:

o Primitive types
All programming languages define primitive types such as integers,
floating-point numbers, and so on. In .NET, such types are value types.
We'll discuss the primitive types in C#, and see how these types map to
Microsoft Intermediate Language (MSIL) data types.
o User-defined value types
We can define our own value types to represent simple objects or small
pieces of data in our application. In C#, structures are user-defined value
types, and are defined using the struct keyword. The .NET Framework
defines custom value types, such as System. DateTime and
System. Drawing. Point, in a similar manner.

15
Chapter 1: Defining Types

o Enumerations
An enumeration is a special kind of value type, which represents a type
that has a small list of allowable values. An enumeration might specify the
values Yes, No, and Maybe for example. Underneath, each of these values
is normally represented by an integer, but defining an enumeration type
allows us to assign meanings to a specific set of integral values.

Unlike Java, both C++ and Visual Basic already support enumerations. The
big difference with C# is that enumerations in the .NET world are strongly
typed. For example, we might have a HairColor enumeration that allows
Blonde, Red, Brown, and Black, and an EyeColor enumeration that can
be Blue, Green, or Brown. This allows us to write readable code, while still
ensuring that we can't aCcidentally give someone blue hair and red eyes.

Primitive Types
c# defmes fifteen primitive types to represent integral numbers, floating-point numbers,
Boolean values, and characters. Eleven of these primitive types are defined by the CLS to
be interoperable with any other CLS-compliant programming language. The remaining
four types are not CLS-compliant, so can only be used in private sections of a C#
application or in any public interfaces where language interoperability is not required.

Each of these primitive types is actually just a synonym for a standard type in the .NET
Framework's System namespace. There is no effective difference between a value type
we define ourselves, and one of these special primitive types. However, these types do
benefit from some special support in the C# language:

o literal syntax: primitive values can all be created using a literal syntax. For
example, when we write float pi = 3.142 f; we are using a literal to
specify a floating-point value. We could use 3 .142d to indicate a double, or
any of a range of suffixes to identify other numeric types. Similar notations
exist for other primitive types, like true and false for Boolean literals.
o Operator support: primitive types can be combined using special operators.
So we can use an addition operator (+) to add two numerical values, or the
'&' or 'I' operators to combine Booleans. In C#, it is also possible to define
operators for our own types. We'll cover this in depth in Chapter 4.

The following table shows the mapping between C# primitive types and the equivalent
structures in the Sys tern namespace. The table also shows how the C# .NET compiler
translates these types into Microsoft Intermediate Language (MSIL) data types during
compilation. Non-CLS-compliant types are marked with an asterisk:

16
Value Types

Primitive Equivalent .NET Equivalent MSn. Description


Type Structure Data Type

bool System. Boolean bool True/False value


byte System. Byte unsigned int8 8-bit unsigned integer
char System. Char char Unicode 16-bit
character
decimal System. Decimal System. Decimal 128-bit decimal value
double System. Double float64 IEEE 64-bit float
float System. Single float32 IEEE 32-bit float
int System. Int32 int32 32-bit signed integer
long System. Int64 int64 64-bit signed integer
object System. Object object Base type of all types
sbyte* System.SByte int8 8-bit signed integer
short System. Int16 int16 16-bit signed integer
string System. String string Unicode string
uint* System.Uint32 unsigned int32 32-bit unsigned integer
ulong* System.Uint64 unsigned int64 64-bit unsigned integer
ushort* System.Uint16 unsigned int16 16-bit unsigned integer

Notice that C# actually lists string and object as primitive types, although both of
these are reference types, not value types. As obj ect is the root of the whole .NET
class hierarchy we'll discuss System.Object further in Chapter 2. However, while most
programming languages include some form of string as a primitive type, the .NET
Framework takes a slightly different approach. For now, we'll use this section to look
at those primitives implemented as value types, and we'll discuss strings when we look
at reference types a little later.

C and C++ developers should be aware that the descriptions given in the table for the
C# primitive types will always be consistent within the .NET Framework. In particular,
in C#, an int is always 32 bits. In C/C++ the size of an int is platform dependent-
although this is commonly overlooked. Similarly, in C#, a long is 64 bits, where in C++
long represents "an integral type that is larger than or equal to the size of type int".
These definitions obviously apply right across all of the .NET languages and this leaves
a little less scope for error when operating in a mixed-language environment.

17
Chapter 1: Defining Types

Visuallklsic Note: Numeric types in C# include both signed and


unsigned versions, which are not available in VB. Be careful when mixing
these types, especially in comparisons. Also, C# does not automatically
convert between numeric types in expressions, so you need to take care
when rounding is important. For example, float f = 1/3 will return
zero, while float f = 1. Of /3. Of will return 0.33333 as expected.

As all types in .NET are objects, we can even invoke methods on literals. This may
seem strange and you'd probably never want to do it, but if we consider a line of code
like string s = 32. ToString () ;, compile and run it, it should help fix in your mind
the "everything is an object" message.

The following simple console application illustrates the use of primitive types in C#:

using Sy tern;

class MyCla s
(
static void Main()
(
int i 100; II use a primitive C. typ
Int32 j • i; /1 use the equivalent .NET Fram ork type

We can use primitive C# data types (such as int) interchangeably with the equivalent
.NET Framework types (such as System. Int32). For the sake of simplicity and
familiarity, you should stick to one set of declarations in your code.

Microsoft is keenly advocating mixed-language programming using any


combination of NET Framework languages. Ifyou are developing a multi-
language solution, you might prefer to use the NET Framework structure
types explicitly, to emphasize the commonality across these languages. For
example, short in C# is the same as Short in Visual Basic NET and
short in Managed Extensions for C++; the equivalent NET Framework
type is System. Int16 in all languages.

Console.WriteLineC"int: (O)", typeof(int} .FullName);


Console.WriteLine("Int32: (O)", typeof(Int32) .FullName);

We use the typeof operator to obtain information about data types at run time and
write this information to the console. The following code asks the user for a numerator
and a denominator and then calculates the quotient.

Console.WriteC"\nEnter a double: "J;

string input = Console.ReadLine();


double nurn = Double.Parse(input);

18
Value Types

Console.Write("Enter another double: "):


input = Console.ReadLine();
double denom = Double.Parse(input);

double res = num I denom;


if (Double.IsNaN(res»
Console.WriteLine("Not a Number.");
else if (Double.lsPositivelnfinity(res»
Console.WriteLine("Positive infinity.");
else if (Double.IsNeqativelnfinity(res»
Console.WriteLine("Negative infinity.");
else
Console.WriteLine("Result is (O}.", res);

We use various methods defined in the Double type to read and process double
values in our application. The Parse method extracts a double value from a string;
IsNaN () tests for "is not a number"; IsPositivelnfinity () tests for positive
infinity (for example, dividing 100 by 0); and IsNegati velnfini ty () tests for
negative infinity (for example, dividing -100 by 0).

When the application runs, it displays the types for int and Int32 as System. Int32;
this confirms that the int type in C# .NET is just another name for System. Int32. The
application also asks us to enter two floating-point numbers; if we enter some arbitrary
numbers, we can see the output on the console.

Save the code into a file called primi ti ve_types. cs, and compile it. Now enter the
following at the command prompt:

C:\Class Design\Ch01> prtmitive_types


int: System. Int32
Int32: System. Int32

Enter a double: 432.33


Enter another double: 4576.33
Result is 0.0944708969851387.

Viewing the Output from the Compiler


The .NET Framework SDK includes several useful tools for examining files generated
when we build a project. One of the most important tools is the MSIL Disassembler;
ildasm. exe. This tool enables us to see how the compiler has translated our C# source
code into MSIL byte code. It also enables us to view detailed metadata for our types,
which can help us understand how the Common Language Runtime works. This in tum
can help us use C# more effectively. We'll look in detail at metadata in Chapter 8.

19
Chapter 1: Defining Types

Some developers dismiss the MSIL Disassembler as being irrelevant and over-hyped,
but that's not the case. We'll be using the MSIL Disassembler extensively in this book,
to investigate how the C# .NET compiler has compiled our code.

To run the MSIL Disassembler tool, open a command prompt (if you are using Visual
Studio .NET, make sure you start a Visual Studio .NET command prompt), then move
to the folder that contains the executable file, and run ildasrn as follows:

The name and location of the executable file depends on how we built the application:

D If we built the application using Visual Studio .NET, the executable file will
have the same name as the project - although with an . exe or . dll
extension - and will be located in the bin\Debug or bin\Release sub-
folder. Also, Visual Studio .NET adds a namespace, which is the same as
the project name.
D If we built the application using the command-line C# compiler, the executable
me will have the same name as the source me, again with an . exe or . dll
extension, and will be located in the same folder as the source me.

For example, if we built the prirni ti ve_types application using the command-line
compiler, we could load up prirni ti ve_types . exe into the MSIL Disassembler.
When you expand the MyClass icon, the MSIL Disassembler window displays the
following information:

..-_---
. WW!J
... ""'
~ ..... NlfEST
. ~,a...

~ ".pN"'No""btIOI~
• do<-o

.......tIt< _ _ _

(
I:A
~ .~. -'~'-'~'~''';-'-P'~'-'- 'J·~="-'d.!J

Double-click the Main icon, to open a view of the MSIL code for the Main method:

20
Value Types

. • thad p.iuAt. htdob~.lg .totie uold IYln(strln,[) or,.) ell .un.g.d

... tr~patnt
.• u<taR In<unu void [ .... a.I1D)S~st ... ST.Th ...d.ttr1DuU:: .• terO •
1/ taU sin 119 I .. Dd)
.ux5tiCk :J
.10 •• 1. lolt (1nU2 V .,
int32 U 1, -
string U_ 2,
flu.t.1I IS 3,
Flootn u- _.
flootn u: S)
Il .... : lde.I_.$ 1..
Il-"I2: sUae.' I
Il: . 13: Idloe ••
Il "A: sUoe.l
Il- IIIS: IdUr "int : (II"
Il- .... : ldto~.n [ ... eorIIDI$~n •• ,lntI2
Il: ..I : caU ..... 1..... rllbl$jJst ••. T~p. 1..... rIlDISl/
t ••• Tl/p,::C"
Il_ " " : uUvirt lnst.nc. string l ... eo.UDlSjJsto •• Typ.: :g.tJulllY.<)
Il_ "19: nil uald [ .. earl1b)S~.t ••. Can.olo: :lIrtt.L!n.( t.lng,
ObJ •• t)
Il I.,.: IdUr "lnt32: (I)"
.( -

In the MSIL code, the Main () method is marked with the MSIL managed keyword.
This indicates code that runs in the managed environment provided by the .NET
Framework Common Language Runtime. All code we write in C# will be managed
code. A variety of local variables can be found described with MSIL data types such as
float64, int32, and string.

Let's look at the end of the IL code for the Main () method:

IL . .1.: can void [ .. earliblSystn.to.. oU: :writtLinf(string)


IL-OIl7f: br.s Il 01ll>e
IL-D081: Idloe .• us
IL-DII83: c.ll bo.l [ ... earl1blSysto~ .Double:: l,posiUvel nflnity( fl .. ,
IL:0Il88: brFaIsl! .s Il 1196
Il DDBa: Idstr "posiUve Infinity,"
Il-DlI8f: c.n void (lIScorUb lSI/,to ... Consol.:: Writ<'llno(strlng)
IL-OI9_: br .5 Il lillie
IL-U96: ldloc .5 US

j
IL-DD98: call Dool (lIScorl1blSl/sto".Doublo:: ISH@gaUuolnflnitylflo.,
1L:.D9d: brfaIsl!I.s Il D.. b
Il ID9f: Idstr "~g.t1v. Infinitl/,"
IL-I"~: call void (lOScorllblSysto ... Cansolo: :Writ,Un.(string)
IL-U.9: br.s IL lillie
Il-nab: ldstr "R'.uIt is (I)."
IL -alibI: ldl.e .s us
Il-OOb2: box [iiseorl1blSlIst... Doubl.
1l:11lII7: call void ( ... corl1blSyst... ConsolO: :lIritolino(strlng.
obJ.et)
IL IDDe: ret
) ,,-.nd of .... thod MyCh .. ::lYln

~=-~==~===="~~==.~.-~~.-~~~ ~~~~~~~~~~~~~ . ~

Each line of IL code consists of a command, followed by any data the command needs to
operate on. Data that the program is working with is stored on the stack. Items are loaded
onto the stack using lL commands that begin Id for load. Each variable on the stack takes
up a fixed amount of memory defmed by its type. For reference type objects, the stack
contains a reference to the location on the managed heap where the actual object is stored,

21
Chapter 1: Defining Types

The first line in the screenshot loads a reference to a string onto the stack. The next
loads the contents of the variable V_5 (which contains the result of the division
operation) onto the stack. When an item is placed on the stack, it goes on top of any
previous stack items. When items are taken off the stack, the top item is removed first.
We'll ignore the box command for a moment, and instead look at the call command.
This call tells .NET to call a method, called Wri teLine ( ) , belonging to a class called
System. Console, found in the mscorlib.dll assembly, which takes as arguments a
string and an object .. NET looks up this method, takes the two items from the top
of the stack and passes them to the method being called. The top item on the stack is
our floating-point value, which is a result of the division we performed. This is not an
obj ect, it's a value type.
We'll look at boxing in depth later as there are some important performance
considerations. For now, we just need to know that the box instruction in the IL code
takes the item on the top of the stack, copies it to the managed heap, and places on
the top of the stack a reference to the boxed value. This allows us to treat the value as
an obj ect and pass it in to this method call. So, when the call to the method comes,
the items on the top of the stack are a boxed value and then a string, and these two
values are passed to the Console. Wri teLine method.

Close the MSIL Disassembler windows when you have finished. if you
forget to close the MSIL Disassembler windows, the EXEfile will remain
locked by the MSIL Disassembler. ifyou try to recompile the application
with these windows open, you 'll get a compiler error because the EXE file
cannot be overwritten.

User-Defined Value Types (Structures)


Applications often require types to encapsulate essentially numeric quantities such as
currencies, screen coordinates, and temperatures, which are not represented by the
available primitive types. Using classes in these scenarios would be like using a
hammer to crack a nut; the run-time overhead for garbage-collecting these simple
objects would be unnecessarily high.
The .NET Framework provides user-definable value types as a solution to this
problem. In C#, a value type is written as a struct. Remember that like value types,
instances of structs are stored wherever they are used.
Value types are messy because they leave copies of themselves everywhere. However,
they are very easy to clean up .. NET doesn't need to keep track of each copy of the
value - if we need the value elsewhere, we'll just send a copy there. Thus if a value
type is no longer reachable, the memory it was taking up is immediately available for
use. With reference types though, we need the garbage collector to sweep up behind
us. All the copies of a reference might have gone out of scope or been overwritten, but
the memory on the managed heap is still being taken up with the referenced object.
We'll see how the garbage collector handles that problem later on.

22
Value Types

Because of the way value instances are passed around, value types should ideally be
small. If we define large value types, inefficiencies start to creep in when we pass the
value instances between methods in our application because of the amount of data that
has to be copied into and out of the method. Large value types will slow down the
allocation, management, and cleanup of objects and stack frames that use them.

In this section, we'll see how to define and use value types effectively in C# and how
to use inheritance with value types.

Defining and Using Value Types


The rules for defining value types are essentially the same as for defining a class. For
example, a value type can have fields, properties, constants, events, methods, and
constructors. As we'll see in Chapters 3 and 4, we can also override methods and
operators and provide indexers just as we can in classes.

Value types, or structures, are cut-down classes, although there are some
important differences:

o Structures must have at least one field or event declaration.


o Structures automatically have a default parameterless constructor. The compiler
will give an error if you try to defme your own. This constructor performs
default initialization for any fields you've declared. It initializes numeric fields to
zero, Boolean flags to false, and sets object. references to null.
o Although we cannot define our own parameterless constructor, we can
(and should) provide parameterized constructors. Feel free to provide
several parameterized constructors where appropriate, so that users of your
value type can initialize their objects in a variety of useful ways.
o We cannot proVide initializers for fields in a structure; we must perform
initialization in a constructor (this is different from a class, where we can
initialize fields at the point of declaration). However, we are allowed to
provide initializers for const fields; that is, we can initialize const fields at
the point of definition. When we look at consts in the next chapter, the
reason for this will become clear.
o Structure objects have a much simpler deallocation mechanism than class
objects. The garbage collector disposes of the class object, and then it calls the
object's destructor just before the object disappears. Structure objects are
deallocated when they go out of scope, or are overwritten with another value,
rather than being garbage-collected. Therefore, it is not permitted to define a
destructor, although we can define a Dispose method in the same way as we
tnight for a class. However, since we can't guarantee it will be called, as we can
in classes, it's best to avoid building value types that require their resources to
be disposed. We'll see an example of this later, although object disposal is
discussed in a little more depth in Chapter 5.

23
Chapter 1: Defining Types

o Many examples show structures with public fields. This seems to


contradict a basic rule of object-oriented development: "don't declare data
public". The tradeoff is one of speed versus encapsulation; public data is
(marginally) faster to access because it avoids the overhead of method calls
to get at the data, but it clearly breaks the encapsulation of the structure. If
in doubt, err on the side of caution and declare all your fields as private.
If private fields are exposed as properties, the accessor code is usually in-
lined by the compiler, resulting in an efficient implementation anyway.
Don't optimize your code at the expense of maintainability; let the compiler
optimize it for you.
o The .NET Framework does not allow us to inherit from a structure. Therefore,
the methods defined in a structure cannot be overridden by methods in a
subclass. One logical consequence of this is that it is not permitted to declare
any member of a structure as virtual, abstract, or sealed. However, the
compiler can predict with certainty which methods will be invoked when we
use structure objects in our code. This insight enables the compiler to
optimize the method invocation for efficiency; for example, the compiler can
choose to expand the method body inline rather than executing a traditional
method call. The net result is that method calls on structure objects can be
less expensive than method calls on class objects.
o As value types, structures are always allocated where they are used. It
doesn't make any difference whether you use the new operator when
defining a variable containing a struct, or not. With reference types, if
you declare a variable but do not use the new operator, the runtime will
not allocate any storage on the managed heap, but will allocate a reference
on the stack containing the value nu11. With value types, the runtime will
allocate the space on the stack and call the default constructor to initialize
the state of the object.

The following example, value_types. cs, illustrates some of these rules:

using system;

struct Money
(
// private instance field
private int centsAmount;

/1 private class field


private const string currencySymbol '$';

// public constructor
public Money(int dollars. int cents)
{
centsAmount = (dollars • 100) + cents;

24
Value Types

II anoeher public constructor


public Money{double amount)
(
centsAmount = lint) «amount • 100.0) + 0.5);

class MyClass
(
static void Main()
(
Mon y fr eoie;
Money salary = new Money(20000. 0);
Money carP rice = new Money(34999.95);

Note the following in this example:

Cl The fields in the structure are declared as private, to maximize encapsulation.


Cl The currencySymbol field is initialized at the point of declaration. This is
allowable because currencySymbol is a const field.
Cl There are two constructors in the structure, to initialize structures in two
different ways. Note the rounding adjustment needed in the second
constructor when we cast from double to into
Cl The Main () method in the separate class MyClass creates three structure
objects, to show how to call the available constructors (including the
compiler-generated parameterless constructor).

At the moment, this program doesn't provide any evidence that it's working. We'll add
some more functionality to it in the next section.

Using Inheritance with Value Types


When we define a structure in C#, we cannot explicitly specify a base class. All value
types implicitly inherit from System. ValueType, which is a standard type in the .NET
Framework library. System. ValueType inherits from System. Obj ect, and overrides
some of the methods from System. Object (System.valueType does not introduce
any additional methods).

When we define our own value types, we can override some of the methods inherited
from System. ValueType or System. Object. One of the most commonly overridden
methods is ToString () , which returns a string representation of the object. For more
information about System. Object, see Chapter 2.

25
Chapter 1: Defining Types

Structures cannot be used as base classes for other classes to inherit; they are not
extensible through inheritance. Structures can be very sophisticated types but they are
not classes. This language restriction enables the compiler to minimize the amount of
administrative code it has to generate to support structures.

Although structures cannot explicitly inherit from an arbitrary class, they can implement
interfaces. For example, it is quite common to implement standard .NET Framework
interfaces such as IComparable, which allows us to specify how objects should be
compared, and so enables sorting. Value types will often implement this to interoperate
well with other classes in the .NET Framework.

We'll be covering interfaces in more detail later in this chapter, but the following preview
demonstrates how easily we can change our Money value type to implement an interface,
and override the ToString () method inherited from System. Object:

II value_type_inheritance.cs
using System;

struct Money ; IComparable


(
II private fields
private int centsAmount;
private const string currencySymbol "$";

II public constructors
public Money(int dollars, int cents)

centsAmount = (dollars * 100) + cents;

public Money(double amount)


{
centsAmount = (int) «amount * 100.0) + 0.5);

II compare with another Money


public int CompareTo(object other)
(
Money m2 = (Money) other;
if (centsAmount < m2.centsAmount)
return -1;
else i f (centsAmount == m2. centsAmount)
return 0;
else
return 1;

II return value as a string


public override string ToString()
{

26
Value Types

return currencySymbol + (centsAmount I lOO.O).ToString():

The Money structure now implements the IComparable interface. The CornpareTo ( )
method, as specified by the ICornparable interface, compares the value of this Money
instance against another Money instance, and returns an integer to indicate the result of
the comparison.

Money also overrides the ToString () method, which is defined in the


System. Obj ect base class. This returns a string representation of this Money instance.
Let's see what effect these changes have:

class MyClass
(
static void Main()
(
II create an array of 5 items
Money[) salaries = new Money[5];
salaries [0) new Money(9.S0);
salaries[l] new Money(4.80);
salaries(2) new Money(8.70);
salaries(3) salaries!2];
salaries (4) new Money(6.30);

II display unsorted array


Console.WriteLine("Unsorted array:");
foreach (Money salary in salaries)
{
Console.WriteLine("{O}" , salary);

II sort the array


Array.Sort(salaries);

II display sorted array


Console.WriteLine("Sorted array:");
foreach (Money salary in salaries)
{
Console.WriteLine("{O}", salary);

In the above example, the Main () method creates an array of Money instances, and
when array element 3 is assigned the value of element 2, it obtains a copy of the value
of element 2. Each Money instance in the array is displayed using
Console. Wri teLine, which implicitly invokes our overridden ToString () method.
The Array. Sort () method sorts the array. For this to work, the array elements must
implement the IComparable interface. Array. Sort () calls the CompareTo ()
method repeatedly on the array elements, to sort them in the specified order. Finally,
the sorted array is displayed on the console.

27
Chapter 1: Defining Types

The application displays the following output:

C:\Class Design\ChOl> valuetype_inheritance


unsorted array:
$9.5
$4.8
$8.7
$8.7
$6.3

Sorted array:
$4.8
$6.3
$8.7
$8.7
$9.5

Enumerations
Enumerations are .NET value types that represent integral types with a limited set of
permitted values. They may also be used to map bit flags onto an integer type to allow
a convenient way to represent a combination of options using a single variable.
Enumerations are present in many programming languages, but in .NET they are also
object-oriented. This means that developers now have access to additional features,
which are not present in other languages.

Enumerated Types
To declare an enumerated type, we use the enum keyword and specify symbolic names
to represent the allowable values. We can also specify an underlying integral data type
to be used for the enumeration (byte, short , int , or long), and optionally assign a
specific number to each of the names.

The following example, enumerations. cs, declares a simple enumeration to


represent medals in a competition:

II enumerations.cs
using System;

enum Medal : short


(
Gold,
Silver,
Bronze

Enumerations inherit implicitly from System. Enum, and so inherit all of its members.
Having defined an enumerated type, we can use it in our code as follows :

28
Discovering Diverse Content Through
Random Scribd Documents
§ 4. Se non ucciso sul fatto, poteva l'adultero essere
punito con altre pene e tradotto in giudizio. Esigevasi però
sempre per le stesse e per la traduzione in giudizio la
flagranza. «έλήφθη μοιχὸς», Lisia, C. Agor., 26. «ἐφ ῇ ἂν
μοιχὸς ἄλω». Demost., C. Neera, 1374. — «μοιχὸς ἑάλω...
ἄνθρα ἐν ἄνθροις (membra in membris) ἒχων» Luc.,
Eunuc. — «Et hoc est quod Solon et Draco dicunt: ἐν
ἒργῳ». Ulpiano.
§ 5. La flagranza riguardava l'adulterio non solo
consumato, ma anche tentato, e non compiuto per
circostanza indipendente dalla volontà dell'adultero.
«Punisce la legge come adultero non solo chi commise in
fatto l'adulterio ma anche chi lo volle o tentò
(βουληδέντα)» — Massimo Tir., Diss. ii.
§ 6. Il marito che non uccide l'adultero, e intende punirlo
d'altra pena, si impossessa della persona dell'adultero
legandolo: o rilasciandolo libero, solo dietro malleveria. Su
la legittimità della cattura, e quindi sul merito dell'accusa
d'adulterio, decide il tribunale. «Se alcuno avrà messo
ingiustamente i lacci ad un altro come adultero, questi lo
accusi ai Tesmoteti: e se vincerà e apparirà legato
ingiustamente, sia libero, e sciolti i mallevadori da obbligo;
se invece è chiarito adultero, i mallevadori riconsegninlo
all'accusatore». — Dem., C. Neera, 1367.
§ 7. Le pene sussidiarie, in luogo e vece dell'uccisione,
sono a piacer del marito o pecuniarie o corporali. Può il
marito accontentarsi di una multa. «È legge l'adultero
multarsi in danaro». Ermogen., De invent., II, 1. — «È
legge l'adultero pagare o morire». — Auct. Probl. Rhet. «E
quegli (l'adultero Eratostene) mi prega, mi supplica di non
ucciderlo, ma di ricever denaro in componimento». Lisia,
Ucc. Erat., 25. «Stefano sorprende Epeneto come adultero
e gli estorce trenta mine: delle quali avuti mallevadori,
lasciò andar libero Epeneto, tenendosi certo del danaro».
Dem., C. Neera, 1367.
§ 8. Le pene corporali, in luogo dell'uccisione, potean
essere di vario genere a piacer del marito: e inflitte nello
stesso recinto del tribunale giudicante sulla legittimità
della cattura. «Se è chiarito adultero, i mallevadori
riconsegninlo all'accusatore, il quale, lì nello stesso
tribunale può far su di lui, purchè senza spada, ciò che
vuole, secondo conviensi ad adultero». (ἄνευ ἐγχειριδιου
χρῆσθαι ὄ τι ἄν βουληθῆ ως μοιχῳ). Demost., C. Neera,
1367.
§ 9. Nella antecedente designazione sono comprese le
pene:
α. dell'accecamento. «Stabiliva la legge potersi
impunemente accecare (τυφλοῦσθαι) l'adultero colto in
fatto». Auct., Probl. Reth., c. 58. «Adulteros deprehensos
licet excœcare». Cur. Fortunatianus, Rhet. Scol.
β. del marchio rovente. «ἔξεστι στιξειν τοὺς μοιχούς».
Hermog., Part. Stat. — νόμος τὸν μοιχὸν στιξειν.
Marcellinus.
γ. del rafano (ῥαφανιδωσις). Faceasi star carponi l'adultero
e pelategli le natiche con cenere calda, gli si ficcava nel
podice un rafano de' più grandi. Suida, alle voci
ραφανιδωθὴναι e μοιχὸς. — Alcifr., Lett., III, 62. — In
luogo di un rafano si usava anche un pesce detto mugile.
Catullo, carm. XV.
§ 10. Il marito che uccide con pene corporali l'adultero
non ucciso sul fatto, risponde di omicidio. — ἄνευ
ἐγχειριδίου, Demost., C. Neer., loc. cit. «Chi bollando
l'adultero, lo uccide, è reo di omicidio». Hermog. e Marcell.,
loc. cit.
§ 11. È condannato il medico che cura gli adulteri,
castigati col marchio o col rafano. «’Ιατρὸς, τὰ τῶν μοιχῶν
ίώμενος στίγματα, κρίνεται» Sopater.
§ 12. Vietato è all'adultero l'ingresso ne' templi. Sop., in
Hermog.
DONNE ADULTERE.
§ 13. Lecito è uccidere l'adultero (colto sul fatto) e
l'adultera insieme. Hermog., Part. St. — Marcellinus, in
Cicer., Rhetor., ii.
§ 14. Il marito che non uccide l'adultera (colta in fatto) è
però obbligato a ripudiarla. «Quando abbia sorpreso in
fatto l'adultera, chi la sorprende non potrà più dimorare
con la moglie: e se dimorerà con essa, sia punito
d'infamia». Demost., C. Neer., 1374.
§ 15. La donna adultera ripudiata non ha dritto alla
restituzione della dote. «È legge che la dote dell'adultera
resti al marito». Sopater. Divis. Quæst. Cfr. Libanius,
Declam., 35. — «Trovando la moglie non costumata e
reputandosi ingannato, la scacciò, gravida, di casa e non
le restituì la dote». Demost., C. Neera.
§ 16. «Legge dell'adulterio. Nè alla moglie (per adulterio
ripudiata) sia lecito entrar nei pubblici templi, se è stata
trovata col drudo: e se vi entri, ognuno possa maltrattarla
a piacere, tranne che ucciderla». Demostene, C. Neer.,
1374. «Perciocchè, se una donna è stata colta con
l'adultero, non può più entrare nei templi per vedere e
supplicare, come può fare una straniera e un'ancella, a cui
lo consentono le leggi. E se le adultere vi entrano in onta
alle leggi, ognuno può maltrattarle a suo talento, purchè
non le uccida. E se la legge eccettuò la morte, mentre
volle impune ogni altro maltrattamento, questo fece
perchè non volle contaminati i templi». Demost., C. Neer.,
ibid. «Solone, dei legislatori il più glorioso, scrisse all'uso
antico decreti solenni sul buon costume delle donne.
Imperocchè alla moglie presso la quale sia stato sorpreso
l'adultero non consente adornarsi, nè entrare nei pubblici
templi, affinchè con la sua presenza non corrompa le
donne oneste. Che se vi entri e se si abbigli, ordina al
primo capitato di lacerarle le vesti e di strapparle gli
ornamenti e di batterla, purchè non la uccida nè la ferisca.
Così il legislatore vitupera questa donna e le crea una vita
peggior della morte». Eschine, C. Timarco, § 183.
§ 17. La moglie accusata d'adulterio può discolparsi dando
il giuramento d'innocenza al pozzo di Callicoro. «A
Mnesiloco Peanese scopersi le impudicizie di sua moglie:
ed egli che aveva ogni modo di appurar la cosa (o uom
proprio di zucchero!) ripose tutto nell'affar del giuramento.
Pertanto la donna condussero al pozzo di Eleusi detto
Callicoro: ivi spergiurò e del delitto purgossi». Alcifr.,
Lett., iii, 69.
SUI LENONI.
§ 18. Ai lenoni era inflitta la morte. «Solone comanda
accusarsi i lenoni, e convinti dannarsi nel capo: perchè alle
persone desiderose di peccare ma vergognose e dubbiose
di trovarsi insieme, danno sfacciatamente e per prezzo
occasione ed agio al delinquere». Eschine, C. Timarco.

202.
Vedi nota antecedente sotto il numero 11.

203.
Cfr. l'orazione di Lisia, in difesa di Eufileto, sulla Uccisione
di Eratostene.
ATTO TERZO

Scena come nell'atto precedente

SCENA I.

Mènecle e Dàmocle tebano.

Dàm. Mènecle, i profughi lasciano questa notte Atene; ma le tue


parole di ieri all'assemblea rimarranno scritte nel cuore dei Tebani.
Mèn. Tebe e i suoi profughi nulla mi devono. Tebe accolse me
profugo al tempo dei 30 tiranni; ho sciolto il debito della ospitalità.
In quanti partite?
Dàm. Pelopida, io ed altri dieci. Il resto dei profughi attenderà, per
seguirci, nostre notizie al confine [204].
Mèn. Lo sapete che in Tebe i tiranni son sulle guardie, che la città è
ben munita, e che la impresa vostra è temeraria?
Dàm. Le nostre braccia sono gagliarde, i nostri petti sono sicuri, le
armi imbrandite per i Lari sono sante. Giove le guiderà.
Mèn. E Giove dunque vi protegga. Bravi figlioli! Vorrei aver vent'anni
di meno per essere con voi!... E avrò vostre nuove?
Dàm. O da Tebe liberata... o dagli inferni.
Mèn. (lo abbraccia) Addio. (Dàmocle esce) Moriranno tutti ma
moriranno bene.
SCENA II.

Mènecle solo.

(Passeggia meditabondo) Ora a colei... Quel maledetto sospetto non


mi dà tregua. Poc'anzi la fantesca parea sulle mosse. Blèpo sarà
ancora alla guardia... Decisamente non mi riconosco più. È bastato
quel sospetto molesto per mandare i miei buoni propositi all'aria!... E
Giove scrutatore dell'anime m'è testimonio s'essi eran sinceri!... Ci
tenevo tanto alla soddisfazione di poter dire: ho schiuso io nuove
gioie, nuovi orizzonti al di lei cuore! Se ella invece ci ha già pensato
da sè, la mia diventa una generosità da far ridere Atene alle mie
spese...

SCENA III.

Mènecle e Blèpo.

Mèn. (ansioso) E così?...


Bl. La vecchia è in trappola.
Mèn. Da quando?
Bl. Ora, ora. Usciva di casa frettolosa: e io salto fuor dal vestibolo:
Alto là, gentil comare, arresta il passo, e vieni un momento con me.
E lei: Impertinente! Sgombra dai piedi! Devo andar per la padrona!
Ed io, prendendola delicatamente: Anderai dopo; intanto
(comicamente declamando) inoltra, inoltra Alceste nella reggia
d'Admeto! E lei: Se non mi lasci la pagherai! — Io te lasciar?
giammai!... Vieni, o fanciulla, e al mio signor rispondi — e dammi il
foglio che nel grembo ascondi!
Mèn. (irritato) Ah! la finisci?...
Bl. Ho finito.
Mèn. E il foglio?
Bl. È qua (Mènecle afferra ansioso il foglio).
Mèn. E la vecchia?
Bl. È là.
Mèn. Entri! (passeggia, concitato, stringendo il foglio con mano
convulsa) Per i fulmini di Giove! non eran dunque sospetti... (fa per
aprire il foglio, poi si arresta) ho paura di aprirlo. Sentiam costei!

SCENA IV.

Mènecle, Tratta e Blèpo.

Tr. (ancora di dentro, piangente, trascinata da Blèpo) Santissime


dee! Mi vuoi lasciare, furfante!...
Bl. (di dentro, declamatorio) Calma, calma, o fanciulla! Umana cosa
è il pianto! (entra, tenendo per un braccio la vecchia) Ecco, o
padrone, la vezzosa Tratta...
Tr. (a Blèpo) Scoppia!...
Bl. ... che da un'ora mi tormenta, perchè vuole parlare con te. (a
Tratta, con far tragico) Parla! favella!
Tr. (piagnucolando) O padrone! padrone! lo giuro a Venere che non
ho fatto nulla e costui mi ha indegnamente maltrattata! (Blèpo fa
gesti comici negativi, come scandalizzandosi dell'asserzione) Fammi
ragione...
Mèn. Comincia a dar ragione di te mezzana indegna!... Scegli tra lo
staffile e il dire la verità... [205].
Bl. (ripetendo con far tragico) Scegli!
Tr. O padrone, sì la dirò, la verità, ma ne attesto le Dee che sono
innocente! Io glie lo davo il foglio, e questo sfrontato senza lasciarmi
tempo, ha allungato apposta le mani sul mio seno...
Bl. Seno, lo chiama! Non le credere...
Mèn. (a Blèpo) Taci, furfante. Esci. (imperioso)
Bl. Ecco la ricompensa!... (va via declamando)

E fuor di casa le fantesce indegne


Van del marito a trafficar lo scorno!... [206].

Seno, lo chiama!...

SCENA V.

Mènecle e Tratta.

Mèn. Alle corte. E bada a non mentire. Da quanto tempo fai questo
ufficio di... Iride messaggiera?
Tr. Che le Furie mi portino via, se non è questa soltanto la seconda
volta.
Mèn. Ah!... (frenandosi) E quando... la prima?
Tr. L'altro ieri.
Mèn. (Il cuore me lo diceva!) E, n'è vero... da Cròbilo?
Tr. Sì, padrone.
Mèn. E Aglae t'avrà detto di non dir nulla...
Tr. Oh no! niente la mi disse...
Mèn. Ed ora da Cròbilo ci tornavi...
Tr. No, no, padrone...
Mèn. Come no? Questo foglio non lo portavi a Cròbilo?
Tr. No.
Mèn. Neghi ancora? A chi dunque, sfacciata? O confessa, o...
Tr. A Elèo.
Mèn. (balzando di sorpresa) Elèo?!! Eh? O quanti ne ha? Elèo?...
(lunga pausa. Mènecle si passa la mano sulla fronte, guarda la
vecchia, guarda il papiro, fa per isvolgerlo, trema di svolgerlo,
s'arresta ancora) No... no... tu menti... non è possibile!
Tr. Buttami dalla torre del Ceràmico [207] se non è vero che ad Elèo
lo portavo...
Mèn. (con accento lungo, doloroso) Anche Elèo!... (si copre,
angosciato, delle mani il volto: poi, cupo, a Tratta) Va. Più tardi con
te aggiusteremo i conti... Blèpo!... (a Blèpo che si affaccia) Tieni
costei sotto custodia!...
Tr. Venere santa!
Bl. Non temere... (trascinandola via) Venere ti ascolterà... Io
attentare al tuo onore!... (escono continuando la vecchia a
lamentarsi e Blèpo a sermoneggiarla).

SCENA VI.

Mènecle solo.

(Passeggia concitato, stringendo febbrilmente il papiro, e dando in


rotte esclamazioni) Eppure l'accento di colei non mentiva... Elèo!...
Elèo ch'io credevo il più leale dei giovani!... Ch'io amavo, e da cui mi
credevo amato come da un figlio!... Ma a questa mia età, non vi è
dunque più un solo volto d'amico, un solo affetto sincero sulla
terra?... Povero imbecille!... i giovani hanno fretta e non aspettano
che la mano gelida di un vecchio rechi loro la felicità! se la pigliano
da sè... (terge una lagrima) Eppure costava loro sì poco l'attendere!
Glie l'avrei ritardata di sì poco!... Addio, mio bel sogno! Coraggio!...
(apre la lettera) È proprio lui!... (Si butta a sedere e riprende a
leggere. Sul principio della lettura, legge forte il grazie della tua con
cui comincia e che gli strappa un'esclamazione e un movimento d'ira:
poi riprende convulso la lettura, ma subito alle parole successive la
sua fisonomia comincia a rasserenarsi e gli sfugge qualche
esclamazione rotta di commozione e di sollievo).
«Elèo!...
«Grazie della tua. Se verrai oggi, sia dunque la tua venuta per dirmi
addio, in presenza dì Mènecle nostro... (a sè, commosso) (Sono
ancora il loro Mènecle! Meno male!) Sì, io ti ringrazio di avere sentito
alla stessa ora, nel cuor tuo, la parola che a me veniva sul labbro.
Aglae ed Elèo non devono più incontrarsi sotto lo stesso tetto, fino a
che Mènecle vive (fra sè, approvando, con inflessione fra comico e
intenerito) (Ciò è onesto!) Ah sì, mio Elèo, noi non possiamo obliarlo
ciò che dobbiamo a quella testa canuta. (Mènecle si asciuga una
lagrima) Ed io più di te: tu lo sai, tu, testimone della sua astuzia
magnanima, per indurmi a riprendere una libertà, che facesse lieti i
miei giorni serbando illibato il mio nome... (Come? come?) tu che
meco leggesti il suo affettuoso addio... (Oh! i mariuoli!) (Mènecle
sorride di gioia e commozione) O Elèo! Vide la Grecia eroi ed eroine,
e sagrifici illustri: non mai ne vide di più veri e più nobilmente
modesti! È dolce la morte per la patria, sapendo di dare ai secoli il
nome: è dolce a vent'anni la morte per la donna amata, sapendo di
averne l'amore: nessun Greco dai capelli bianchi affrontò per una
fanciulla ciò che è ben peggio della morte: vivere vecchio, solo e
sconsolato. (Mènecle vinto dall'emozione, s'asciuga una lagrima e
sorride) (Ma come sa scrivere quella birichina!) Oh, io rimarrò con
Mènecle fino all'ultimo de' suoi giorni... (Se io lo permetterò!)
superba che tu mi approvi... (Ah lui approva! Bravo!) Farò di tutto
per consolare quell'anima generosa che ha amato troppo in gioventù
per non sentir bisogno di qualcosa che le rammenti il passato. Vedi,
ieri, col solo aver dato al suo cuore la occupazione della gelosia...
(La briccona!) il povero vecchio pareva tutto cambiato: a quest'ora,
scommetto, non pensa già più al suo triste disegno, inseguendo
questa piccola cura che lo molesta e lo alletta, gli sveglia il ricordo di
emozioni antiche. Forse già sospetta di Cròbilo: e io tollero per ora le
visite di quell'imbecille... (Cròbilo fa progressi!...) che anch'oggi
verrà... Ma non confondiam la commedia con le cose serie. Addio,
Elèo, addio, amico. Gli Dei ti proteggano... e ti serbino un giorno...
(Ti serbino...?) (Mènecle che man mano verso la fine è venuto
leggendo sempre più rapido e sicuro, con volto ilare e accento
concitato per gioia ed emozione, giunto a questa parola,
improvvisamente si arresta, ritorna scurissimo in volto e depone il
foglio con espressione angosciosa. Una visibile lotta si combatte nel
suo animo. Parecchie volte fa atto di padroneggiarsi per continuar a
leggere il resto della frase, e altrettante esita. Infine con uno sforzo
penoso ma risoluto pone l'occhio sulla carta, e alle parole che
terminano la frase e la lettera balza in piedi con un urlo di gioia)...
all'onor della Grecia!» Ah! Molto ben detto.
(Mènecle, rasserenato, contento, passeggia su e giù discorrendo
seco con vivacità febbrile) Ma non si dirà mai che Mènecle a
sessantacinque anni si è lasciato sopraffare in generosità da due
fanciulli! E quella birichina che s'intende di burlarmi, la burlerò io!...
Bravi figliuoli! Che Giove vi benedica — per il bene che volete a
questo povero vecchio... (dopo una pausa, intenerito) e per quello
che vi volete tra di voi! Quanto a quella buona lana di Cròbilo —
l'imbecille Cròbilo — eh, se stesse a lui, non lo è poi tanto — farà i
conti con Aglae... e con sua moglie... (va all'uscio e chiama) Blèpo!

SCENA VII.

Mènecle, Blèpo e Tratta.

Mèn. (a Blèpo) Conduci qua la vecchia. (Blèpo esce) Questa lettera a


ogni modo è troppo bella e merita che Elèo la veda! Queste cose... a
quell'età... fanno bene!... educano il cuore dei giovani!...
Bl. (di dentro) Coraggio! che il padrone è allegro! Tergi l'amaro
pianto!...
Tr. (ancora piagnucolosa) Oh mio buon padrone...
Mèn. Non tante smorfie... Riprendi questa lettera e riportala al suo
destino. E Aglae non sappia che m'hai parlato. [208]
Tr. Sì, sì, padrone!
Bl. (a lei che se ne va, nell'uscire assieme) Vedi? «dopo le nubi —
nella reggia d'Admeto il sol risplende...»
Tr. (a Blèpo nell'andarsene) Lo vedi se ero innocente, o birbante?...
Bl. (fingendo indignarsi, con posa tragi-comica) Fanciulla!...
Tr. Faccia da gufo!...
Bl. Vezzosa Venere!... io attentare al tuo seno!... (vanno via
bisticciandosi, la vecchia collerica e Blèpo gravemente canzonatorio).

SCENA VIII.

Mènecle solo.

Ed ora... Oh! il gnomone segna la nona... Se Cròbilo ha da venire, a


momenti sarà qui. Adesso gli lascio più tranquillo il posto... e lo
servo io... Ah, eccolo... l'imbecille Cròbilo... (s'avvia ad uscire dalla
porta interna, ch'è nel mezzo) Non guastiamogli i progressi!...
Quanto ai due ragazzi poi... (Nello andarsene, si arresta ad un tratto,
essendosi fermato il suo sguardo sopra una vecchia panòplia appesa
alla parete. La sua faccia, dianzi rasserenata, si è rifatta seria, triste,
pensosa. Sembra assorto in qualche improvvisa idea. Distacca
macchinalmente dalla panòplia una vecchia spada, la sfodera, e
l'esamina lungamente) Quanta ruggine!... (cogitabondo, brandisce
due o tre volte la spada, squassandola, come per provar la forza del
braccio. Poi, come soddisfatto della prova, con gesto rapido, la
rinfodera, la rimette a posto, va concitato ad un tavolo, scrive poche
righe, poi chiama) Blèpo! (Blèpo compare) Questo a Pelopida!... (gli
consegna una tavoletta quindi va via ripetendo con accento di
soddisfazione commossa) Quanto ai due ragazzi poi... (esce).
SCENA IX.

Cròbilo solo.

(Voce di fantesca di dentro) Aspetta qui — verrà a momenti.


Cròb. (si avanza guardingo, pauroso, dal peristilio a destra, in punta
di piedi, spiando intorno) La piazza è deserta. (rassicurato) Meno
male!... (tentennando il capo) Curiosa! La mi fa venir qui —
evidentemente è un convegno — e invece di ricevermi nelle sue
stanze, la mi riceve nell'aula comune... Basta! speriamo avrà preso le
sue misure... Non ci avrei nessun gusto di incontrar Mènecle. Mi
squadrava ieri e mi contava quegli atti di ferocia, con una
disinvoltura... Brrrr!... Mènecle sarà un buon amico, ma non è uomo
mite nell'arte di governo... e non è quello il sistema di cattivarsi le
popolazioni!... Ma già, nelle sue cose è un po' strambo... non l'ho
mai capito troppo bene... Quello che capisco benissimo è che Aglae
con lui non se la intende... Ah, ella è qui... Numi! come è bella! par
Venere che esce dalle spume!

SCENA X.

Cròbilo e Aglae.

Agl. (entrando con far cordialissimo, disinvolto) Salute, buon


Cròbilo!...
Cròb. (misterioso) Ssssss!...
Agl. (forte, mostrando sorpresa) Che è?...
Cròb. Ssssss! (sottovoce, facendole segno di parlar più piano) C'è del
nuovo.
Agl. Nuovo di che?...
Cròb. (con gesti) Tu non sai...
Agl. Che cosa?
Cròb. Mènecle... (parla esitante, sconcertato dalla tranquillità con cui
Aglae lo guarda) ha dei sospetti...
Agl. (disinvolta) Fa benissimo. È il dovere di un marito di averne.
Cròb. (sconcertato) Eh? (Cosa dice?...) E... tu...?
Agl. E il dovere di una moglie è di lasciarglieli.
Cròb. (tentennando il capo, fra sè) (Comincio... a non capire). (ad
Aglae) Ah... già...
Agl. (senza darsi per intesa della sua sorpresa) Meglio in faccia a
Giove custode dei giuramenti essere moglie sospettata... (moto di
compiacenza di Cròbilo) ... anche ingiustamente... (gesto di
disappunto di Cròbilo) dal marito, che essere marito ingiusto colla
moglie...
Cròb. (rasserenasi) (Ora mi raccapezzo!) Ah sì! Mènecle è ingiusto,
più che ingiusto... con te... (E governava le isole in quel modo...!
Prudenza! Battiamo largo!...) Però, se egli pensasse a risarcire...
Agl. Credi tu che gli anni di una fanciulla sciupati nella solitudine si
risarciscano?... Tu non sai...
Cròb. So, so!... (Povera ragazza!) Ma tu sola non sei... vi hanno cuori
che ti sanno compiangere...
Agl. (con accento vibratissimo, sdegnoso) Compiangere?... Aglae
non ha bisogno di compianto. Alla mia età, si sente; alla mia età si
ama, intendi?...
Cròb. (guardandola con compiacenza) (Eh! come lo dice!...)
Agl. (incalzando) Alla età mia, c'è qui dentro un cuore che batte, c'è
un'anima che ferve, che soffre, che s'irrita, che ha bisogno del suo
lembo di mondo e di cielo!... E quando la povera anima piange
trovandosi al buio, quando si lagna perchè trovasi al chiuso... la si
compiange! Bel conforto! tenetevelo!
Cròb. (Ha ragione!) No... Aglae... senti...
Agl. (non dandogli retta, e in vista di sempre più accalorarsi) No...
non è questo che essa chiedeva! Questa oscurità mi intristisce:
datemi la mia parte di luce! questo chiuso mi soffoca: datemi la mia
parte di aria!... Aprite! aprite! Questo volevo!... (si abbandona come
spossata dallo sforzo, su di una sedia: poi dopo una pausa,
volgendosi a Cròbilo) Oh, Cròbilo... perdona... mi dimenticavo e ti ho
annoiato co' miei lamenti...
Cròb. Annoiarmi! ma va avanti!... ma va avanti! Parlano in tua bocca
le Sirene!
Agl. E or che ci penso, ho avuto torto di rispondere alla tua... e di
farti venir qui...
Cròb. Perchè?
Agl. Perchè il favore che avevo a chiederti...
Cròb. (fra sè, malizioso) (Pretesti!...).
Agl. ... tu non puoi farmelo...
Cròb. (concitato, insinuante, carezzevole) Ecco... vedi... ciò si chiama
essere ingiusti... Aglae, non hai mai udito dire che le anime colpite
dalla stessa sventura tendono, per istinto, a ravvicinarsi? Io, dianzi, ti
ascoltavo commosso...
Agl. (a parte) (Brutto ipocrita!) E tu...
Cròb. E chi ti dice che anch'io non sia uno spirito sofferente che
inseguiva uno splendido ideale, strappatogli dalla triste realtà? Il mio
ideale era un'anima che comprendesse la mia... si chiamava: la
bellezza, la felicità, l'amore...! la realtà si chiama... (con voce cupa)
Mìrtala!...
Agl. (a parte) (Qui ci vorrebbe lei!)
Cròb. Io, vedi, m'ero detto: Ecco, o Cròbilo, gli Dei t'hanno dato la
generosità, la virtù...
Agl. (la modestia...)
Cròb. ... tu hai da essi una bella missione nel mondo. Troverai sulla
tua strada la menzogna, e la smaschererai; troverai la sapienza, le
strapperai i segreti; troverai la gloria, le darai le corone; troverai la
virtù, la assisterai; la sventura, la consolerai...
Agl. (... tua moglie, la tradirai...)
Cròb. ... Aglae, tu sei sventurata... e mi vuoi togliere il conforto di
esercitare sulla terra... la mia missione?
Agl. Oh no... ma...
Cròb. Ne dubiti...
Agl. No, ma, vedi, è una missione pericolosa la tua. L'ultima volta
che fui a Corinto, passando in lettiga dalla piazza del mercato, vidi la
casetta di Antifonte l'oratore, quello, sai, che Atene condannò a
morte poco tempo prima di Socrate... E mi fermò la scritta che era
ancora sulla porta: «Ufficio di consolazioni. Qui dimora Antifonte, il
quale ha la virtù di guarire con parole gli addolorati...» [209] La tua
missione medesima! e l'umanità glie n'è stata così riconoscente, che
lo ha condannato a bere la cicuta...
Cròb. Alla quale noi rinunziamo! L'umanità è stata sempre ingrata.
Ma Antifonte guariva con le parole... e non coi fatti...
Agl. (suggestiva, velatamente ironica) E tu invece... uomo di fatti,
sei!... Ma da quando questa missione il tuo buon demone t'ha
suggerito di esercitarla?... Fino a ieri nulla ne seppi... e poi, Aglae,
supposto avesse bisogno di un consolatore, vorrebbe prima
accertarsi che sia quello veramente che ebbe quest'incarico dai
Numi: che sappia indovinar nella sua anima ogni fremito de' suoi
desiderî, ogni sussulto delle sue speranze, ogni lagrima dei suoi
dolori... (dopo dette queste parole con voce insinuantissima,
mutando a un tratto bruscamente accento) ... vedi bene che tu non
puoi essere quello...
Cròb. (vivissimo) E se lo fossi?...
Agl. Se lo fosti anche... non ne troveresti il tempo...
Cròb. (incalzante) E se lo trovassi?...
Agl. (fingendosi perplessa) Se lo trovasti... (con pentimento brusco)
E poi no...
Cròb. Mettimi alla prova...
Agl. Davvero? E tu sai...
Cròb. So tutto.
Agl. E acconsentiresti...
Cròb. Se acconsento!... (fra sè, un po' sconcertato) (Consentire??...
che diamine?...)
Agl. Oh grazie!... Perchè capisci... dal momento che tu sai tutto...

(Batte su queste parole con insistenza maliziosa).

Cròb. (impaziente, incalzantissimo) Tutto, tutto...


Agl. Non ci sei che tu... E tu dunque gli parlerai?... quando?...
Cròb. (sbalordito) Parlare... a chi?...
Agl. (con tutta naturalezza) Ma a lui...
Cròb. (sempre più sbalordito) Già... già!... Ma... lui... chi?...
Agl. Ma a Mènecle...
Cròb. Eh?!... (dà uno sbalzo di spavento) (Quella ci mancherebbe!...
con quel po' po' di sentenze!...) (sconcertatissimo, e pure
sforzandosi nasconder l'imbarazzo) Ah... già, già... Ma...
Agl. (fingendo non accorgersi del suo turbamento) Ma tu vedi che da
qui bisogna uscirne, per le Dee!... bisogna uscirne!... Esiti? Ah!... lo
sapevo...
Cròb. (con uno sforzo) Ma ti pare?!... Niente affatto!... (facendo la
voce risoluta e cercando farsi coraggio) Cròbilo non indietreggia... e
se tu lo vuoi... (vorrebbe dir qualche cosa, ma gli manca il coraggio)
Ma permetti una parola...
Agl. (impaziente) Cosa?...
Cròb. ... nel tuo interesse... mi pare... non ti pare... parlargli io... fare
uno scandalo...
Agl. Scandalo? (fingendo sorpresa) Scandalo il dirgli che fa male a
trattare così la sua compagna, sposata innanzi agli Dei patrî ed agli
Dei del focolare?... il dirgli, coll'autorità di un amico, che non son
questi i giuramenti innanzi all'arconte; scandalo il dirgli che sua
moglie soffre...
Cròb. (balzando sbalordito) Eh?!
Agl. ... scandalo il ricondurmelo?...
Cròb. (sbalordito più che mai) (O Febo! o spiriti! lo ama!) E... e...
questo era... che volevi?
Agl. (mostrando a tutta prima sorpresa della sua sorpresa) E che
altro... dunque... imaginavi?... Ah!... (quasi un pensiero le balenasse,
si fa improvvisamente scura in viso, e s'appressa a Cròbilo,
figgendogli gli occhi in faccia, e parlandogli con voce lenta,
severissima) Che altro imaginavi che il labbro di Cròbilo, marito di
Mìrtala, potesse osar di confessare all'orecchio di Aglae, la sposa di
Mènecle?...
Cròb. (interdetto, confuso) Io... nulla... nulla... Ma le tue parole...
questo invito...

(Da qualche istante è entrata in iscena Mìrtala introdotta


adagio da Blèpo, che le fa dei gesti maliziosi, sulla soglia,
additandole Cròbilo; vedendo questi, Mìrtala si arresta, e
ritraesi alquanto).

Agl. (seria e dignitosissima) Il mio invito fu un torto... se ebbi torto


di crederti amico leale di Mènecle e mio... Ma se Mènecle...
Cròb. (spaventato, supplichevole) No!... no!... (concentrandosi e
meditabondo, coll'indice sotto il naso) (Ma dunque... avrebbe quasi
l'aria di essere una canzonatura?!...)
Agl. (proseguendo) Ma se tua moglie... fosse qui... (Aglae s'è
accorta della presenta di Mìrtala) se ti sentisse... che cosa direbbe di
questa tua improvvisa meraviglia?...
Cròb. (prorompendo, con voce risoluta, irritata) O per gli Dei! se mia
moglie mi sentisse... le direi...

SCENA XI.

Detti e Mìrtala (già in iscena da qualche minuto).

Mìrt. (si è avanzata dalla soglia lentamente, e non vista da Cròbilo,


le si è posta a lato, senza guardarlo, ritta, la testa alta, le mani sui
fianchi) Sentiamo!
Cròb. (voltandosi con ispavento alla voce di Mìrtala) (Mia moglie! son
morto!) (cercando ricomporsi dalla paura, e uscirne, alla meglio, con
accento garbato) Niente!... direi che la sposa di Mènecle ha dato a
Cròbilo una prova di stima e di fiducia che lo onora... (a denti stretti)
(Questa non me l'aspettavo!) Cara Mìrtala, sai... (tenta parlarle con
fare sciolto e sorridente, ma lo sguardo minaccioso di Mìrtala, fisso
su di lui, lo sconcerta) (Che occhiacci! Giove me la mandi buona!)
Mìrt. (con voce lenta e severa, squadrandolo) So... E spero che
l'incarico lo adempirai... (abbraccia Aglae) Grazie, buona Aglae! Non
dubitavo di te. [210] Eh, pur troppo noi donne siam sempre
circondate di insidie!... Quanto a questo Alcibiade sbagliato...
(squadrando Cròbilo) regoleremo i conti a casa...
Agl. A tempo sei giunta, cara Mìrtala. Ma sii buona con Cròbilo. Io gli
chiesi un favore che egli meglio d'altri può rendermi... fui forse
indiscreta... ma la sua bontà fu maggiore della mia indiscrezione... (a
Cròb. cordialissima) Grazie, Cròbilo! (velatamente ironica, affabile)
Oh, sì, gli Dei ti hanno data una ben nobile missione! Troverai la
sventura, la soccorrerai;... le mogli abbandonate... ai lor mariti le
renderai...
Cròb. (con ismorfie) (Nella mia missione questo non c'era...)
Agl. Sicuro, Mìrtala, ei m'ha promesso di rendermi il mio Mènecle... è
un'anima bella, il tuo Cròbilo... Sii buona con lui.
Mìrt. Non dubitare, non dubitare. Se non fossi buona, gli avrei
portato quattro talenti di dote...
Cròb. (premuroso, tentando ingraziarsela) E la possessione di
Egìna... terreni aratorî di prima qualità...
Mìrt. (fissandolo severissima) Precisamente. E che i colòni
trascurano e abbisognano molto di sorveglianza. Ci andremo
insieme...
Cròb. (con esclamazione comica di angoscia) (Ohimè!... l'esilio!...
come Aristide... ma almeno Aristide era solo!...)
Mìrt. Frattanto, in attesa di parlar con Mènecle, ti rincrescerebbe
accompagnarmi?
Cròb. Ma eccomi!... (fra sè, ripetendo dolorosamente) (L'esilio!...
come Temistocle!)
Mìrt. Addio Aglae...
Agl. Addio Mìrtala. Grazie, Cròbilo...
Cròb. (con uno sforzo sopra di sè) Nulla, nulla, mio dovere...
(Decisamente... era proprio una canzonatura!...) (ad Aglae) Nulla!...
(a Mìrtala) Eccomi... (con comica angoscia) (L'esilio!... come
Alcibiade!)

(Si lascia macchinalmente condurre via da Mìrtala, con aria di


suprema dolorosa rassegnazione).

SCENA XII.

Aglae sola.
(Seguendo Cròbilo dello sguardo) Imparerai meglio un'altra volta la
missione del consolatore... (pausa; poi fattasi triste, pensierosa,
sospirando) Eppure, soltanto la povera Aglae lo sa, se il suo cuore
avrebbe oggi bisogno davvero di conforto!... Coraggio!... Fra breve
egli sarà qui a dirmi addio... Povero Elèo! (leva dallo strofio un
piccolo papiro e legge)

Te fuggo com'esule che disse l'addio...


Ma volge la testa tornando a guardar!...
E fugge... ma il segue più lungo il desio...
E fugge... ma indietro vorrebbe tornar!
Mia triste, mia triste battaglia del core!
Scrutarla non cerchi pupilla di uman!
Lasciatemi questo mio povero amore!
Per viverne solo, lo porto lontan!

Egli è qui!... Venere santa, dammi forza tu!..

SCENA XIII.

Aglae ed Elèo.

Agl. (con effusione triste) Elèo!...


El. Aglae! Ebbi la tua. (commosso, cercando padroneggiarsi e parer
calmo) Grazie... Reco gli addii a Mènecle e a te.
Agl. (triste, commossa) E tu parti...
El. Stanotte.
Agl. (vivamente inquieta) Per dove? con chi?
El. Con Pelopida tebano e i compagni suoi. (esclamazione di Aglae)
Tebe accolse mio padre esule al tempo dei tiranni: è giusto che
nell'ora delle sue sventure, il figlio paghi il debito dell'ospitalità...
[211]
Agl. (vivissimamente) E tu...
El. E io seguirò i fuorusciti nella più santa delle imprese.
Agl. (dolorosamente esclamando) O Dee!

(Si abbandona sur un sedile, sopraffatta dall'emozione e


piange).

El. Avresti preferito sapermi vivere, da te lontano, una vita oscura,


ignava, ingloriosa? Ignavia per ignavia, tanto allora varrebbe la
colpa!...
Agl. (asciugandosi gli occhi e cercando padroneggiarsi) No, no!
Perdona... hai ragione... Ma tu sei eroe, figlio di eroi, ed io, dopo
tutto, non sono che una fanciulla. Perdona. Vedi. Sono forte ora.
(parla con voce rotta, reprimendo i singhiozzi) Ti guardino i Numi!
Oh nessuna preghiera sarà mai loro salita più fervida delle mie! Ti
guardino i Numi! E ricordati di Aglae!..
El. Ricordarmi?! La tua lettera verrà meco come la voce del buon
genio mio. Le tue parole mi han fatto triste insieme e superbo. Tutta
la mia esistenza, dissi a me stesso, mi parrà spesa bene, se sarà
spesa a meritarmele. Quando le ore mi passeranno più tristi, dirò:
Coraggio!... la stima di Aglae è con te. Quando la lontananza mi
parrà più incresciosa, penserò che è per Aglae che l'affrontai: e che,
se al mio nome, tra i Greci, verrà qualche gloria, Aglae lontana lo
saprà. Così avrò una ambizione nella mia vita, una luce sulla mia via.
E se un giorno sentissi le forze mancarmi, e farmisi uggiosa la luce
cara del dì... vorrà dire che Aglae m'avrà dimenticato...
Agl. Oh Elèo! sei cattivo! e non dovresti esserlo con la povera Aglae
in quest'ora!... Ecco, io avevo preparato un bel ricordo che avrebbe
fatto qualche volta sovvenire ad Elèo la sua piccola sorella d'infanzia:
così Aglae, pensavo, fida restando al dover suo, potrà viaggiar senza
rossore in compagnia dell'amico de' suoi primissimi dì... (mentre
Aglae parla, come fra sè, con voce carezzevole, infantile, ha nelle
mani un piccolo ritratto all'encausto, che si è levato dallo strofio, e
che va guardando) vedrà con lui altro cielo ed altre città della Grecia:
e come egli la vedrà sempre sorridergli così... dello stesso sorriso,
fissarlo sempre con lo stesso sguardo, come uguali rimarran sempre
queste dipinte sembianze, così uguali per Elèo rimarranno la
memoria ed il cuore di Aglae...
El. (vivissimamente, facendo atto di prenderle il ritratto dalle mani)
Il tuo ritratto!... Oh grazie!
Agl. (con umore) Grazie niente. Mi hai detto quelle brutte parole...
El. Aglae!
Agl. Ho fatto male a dirti di venire. Era meglio non vederci... Va...
lasciami...
El. Ma non prima di aver meco questo pegno, che non darei (glie lo
toglie con affettuosa violenza: Aglae se lo lascia togliere, senza
guardar Elèo) pei tesori della terra! non prima di averti detto che
Elèo parte, ma la sua mente e la sua anima rimangono qui:... qui,
presso al piccolo domestico altare, dove orfano appresi ad amare i
soli esseri che mi amarono al mondo e ad accettare per essi il
dolore... a comprendere, per essi, il sacrificio!... (con trasporto
vivissimo) Oh andassi fino agli ultimi confini del mondo ed agli
Espèridi... lascierà prima Pallade la nostra rupe, che queste soglie,
ove tu vivi, il mio pensiero!...
Agl. No, no, Elèo!... capisco di chiedere troppo... troppo più che io
non deva, al tuo cuore ed alla tua memoria... Tu sei bello, sei
giovane, e non potrai, non dovrai vivere sempre solo...
El. (con rimprovero) Aglae!...

SCENA XIV.

Detti e Mènecle.

(Mènecle si è affacciato dalla porta nel fondo, mentre Elèo ed


Aglae proseguono il lor dialogo sul davanti della scena.
Rimane muto, le braccia conserte, il volto tra pensieroso e
sorridente, sulla soglia a guardarli).

Agl. No... lasciami dire... Non ti accuso... Il tempo non muterà la tua
tempra, ma muterà molte cose intorno a te... Mènecle vivrà, e glielo
auguro, buon vecchio! molti anni...
El. (melanconico) Oh... anch'io...
Agl. ... e il giorno che io sarò libera di nozze, io non sarò più una
ragazza per te. Breve è la stagion della donna — e s'ella non la
coglie — passata quella, se ne sta seduta a consultar gli auguri [212].
Le rose della giovinezza in quel dì saranno svanite, e a te, nel fior
degli anni, non resterebbe a sposar che la memoria e l'ombra di colei
che fu un tempo la bella Aglae... una brutta vecchia grinzosa... Oh,
sarebbe troppo pretendere...
Mèn. (di dietro, tentennando il capo) (Infatti...)
Agl. ... e faresti la figura di Cròbilo. Direbbero che m'hai sposata per
godere la mia dote, la eredità di Mènecle. No, no, promettimi solo
che il giorno in cui il tuo cuore sarà stanco di attendere... rimanderai
ad Aglae questo ricordo...
El. Fino a che tra i viventi mi rischiari il sole, questo ricordo starà con
me. Verrà con me nella pugna, poserà con me sotto la tenda. Oh gli
anni possono involarci la cara giovinezza, spegnere le febbri, i delirî
dei sensi, ma non ispegneranno un affetto reso puro e santo dal
sagrificio...
Mèn. (È nato per far l'oratore!...)
El. (con forza) ... prima che io rinneghi la fede di questo affetto,
possa Nettuno farmi morire come Ippolito... e casto come lui!...
Mèn. (Povero ragazzo! te ne accorgeresti!...)
Agl. (buttandosi al collo di Elèo) Oh... lasciamo questi giuramenti...
Mèn. (To'! ha più giudizio di lui!...)
Agl. Sia dell'avvenire e del cuor tuo quello che gli Dei vorranno. Io ti
ringrazio del conforto che m'hanno dato le tue parole. Esse mi
renderanno più forte in questa prova... Che se vi avessi a
soccombere... (con voce triste, infantile) dirò a Mènecle che mi
faccia un bel sepolcro tutto bianco... bianco... e tu ci verrai...
El. Oh taci! Non parlar di morire; dimmi che in te la memoria di
quest'ora non morirà... Me lo prometti?
Agl. (volgendosi all'altare domestico) Qui all'ara del Dio che ci
ascolta...
El. E mi giuri che se Mènecle...
Agl. (senza guardar Elèo, esitante, gli occhi a terra) ... il buon
vecchio Mènecle...
Mèn. (Poverina! ci ha aggiunto anche il buono!..)
Agl. (arrestandosi e riprendendo premurosa) ... che noi dobbiamo
amare, finchè vive, come fosse nostro padre, n'è vero?
El. (triste, a capo basso) Oh, sì... come un padre...
Agl. (riprendendo esitante il filo della frase) ... se il buon vecchio
Mènecle ci venisse un giorno rapito dalla Parca triste...
El. ... inesorabile!...
Agl. ... scellerata!...
Mèn. (c. s.) (Si sfogano colla Parca... meno male...)
El. ... e che io fossi vivo...
Agl. E io anche...
El. E tutti due...
Agl. E tutti due quella perdita... amara... (appoggia la voce
sull'amara, quasi volesse correggere un pensiero colpevole: Elèo
assente col gesto) ci trovasse ancor giovani... in età da marito...
(Sempre esitante, a occhi bassi, come avesse paura o rimorso
di compier la frase)

Mèn. (Giustissimo!... a maritarsi vecchi, ecco ciò che succede...)


El. Quel giorno dunque...
Agl. Che il buon Mènecle...

(Mènecle si avanza fra i due giovani).

Mèn. (proseguendo la frase, a voce alta) ... andrà all'altro mondo...


El., Agl. (sgomentatissimi entrambi al vederlo) Ah!...
Mèn. ... speriamo, neh, figlioli, che sia lontano — quel giorno
piangeremo prima amaramente la sua partenza e poi potremo
sposarci senza scrupolo. Ma sentite, neh! (picchiandosi lo stomaco)
che polmoni e che cassa di stomaco! Ce n'è ancora per trent'anni!...
Se aspettate me state freschi!
Agl. (buttandosi alle sue ginocchia) Oh perdono, Mènecle!...
El. (idem) Perdono... padre mio...
Agl. Ti giuro, per le Dee, che...
Mèn. (rialzandoli entrambi con affabilità affettuosa) Su, su, ragazzi!...
ma che giuramenti e che perdoni! So tutto... Grazie a te, Elèo, della
tua lealtà; grazie, Aglae, della tua fedeltà al tuo dovere. Soltanto,
speriamo (con bonarietà comica) non mi farai più dell'altre scene di
gelosia...
Agl. (mortificata chinando gli occhi) Mènecle!...
Mèn. No, no — non ti rimprovero... benchè, per Giove, lo meriteresti,
per insegnarti a frugare nelle carte del marito e a leggerne le
lettere...
Agl. (sorpresa, mortificata) Ah!...
Mèn. ... e a scriverne dell'altre ai giovinotti, a sua insaputa...
Agl. (mortificata) Come... tu...?
Mèn. (con bonarietà comica e imperiosa) Silenzio!... Sappiamo tutto.
Se la moglie fa la curiosa, il marito ha diritto di fare il curioso... (a
Elèo) Neh, ricordalo bene anche tu, una volta che sii suo marito...
Agl. (supplichevole) Oh... Mènecle!...
Mèn. Silenzio!...
El. (interpretando anch'egli come ironia le parole di Mènecle)
Mènecle, punisci me... ma risparmia a me ed a lei le tue ironie...
Mèn. Ma che ironie?!! Le tue vuoi dire. È una moglie divisa in due —
a me in corpo, a te in effigie — non è un'ironia? E cosa credi, che
Mènecle sia feroce come Teseo, da lasciar morir casto il povero
Ippolito? Cosa credete (ad entrambi) che Mènecle sia così egoista,
così disonesto, così imbecille da accettar la elemosina del vostro
sagrificio? (Mènecle, stando in mezzo ai due giovani, ha proferito
queste parole con impeto e voce brusca; i due giovani, sotto la
sfuriata del vecchio, tengono mortificati la testa e gli occhi bassi;
quando al finir delle sue parole s'attentano a levarli furtivamente
verso di lui credendolo in collera, s'accorgono che Mènecle sorride
del loro inganno, e li guarda affettuoso facendo lor cenno, delle due
braccia, di appressarglisi) Voi altri siete così matti che lo avreste
anche mantenuto... ma poi... poi, neh? (si volge ad Aglae
affettuosamente canzonandola e rifacendole la voce) le forze
mancavano... e ci voleva il sepolcro bianco... tutto bianco... (con
rimprovero comicamente brusco) farmi far di queste spese!...
Ohibò!... Tu... (sempre ad Aglae) in castigo della burla che m'hai
fatto, — e tu in castigo (ad Elèo) del non avermi mai detto niente —
quando si ama la moglie si avvisa il marito — vi mariterete... E così
imparerete.
Agl., El. (gettandosi entrambi commossi al collo di Mènecle) Ah
Mènecle, mai!
Mèn. (con voce grave, liberandosi dall'abbraccio dei due, piangenti di
commozione) Preferireste vivere, aspettando senza volerlo, senza
saperlo, la morte mia?... (ad Aglae) Oggi tu ed io andremo
dall'arconte, a deporre la scritta del divorzio insieme: e ci verrai a
fronte alta, perchè tu rimani nella mia famiglia... (movimento di
Aglae e di Elèo) già, nella mia famiglia... tu sposi mio figlio
adottivo... [213].
Agl., El. Ah!...
Mèn. (proseguendo, ad Elèo) ... se non ti rincresce passare dalla tua
nella mia tribù, [214] verrai meco dai fràtori del borgo di Alopéce, e
sarai iscritto nel registro della fràtria mia, come mio figlio, — erede
con lei (accennando Aglae) delle mie fortune, partecipe delle cose
sante e sacre [215]. Porterai in nome Làmaco: il nome di mio padre
caduto da valoroso a Samo... e nella famiglia di Mènecle al nome
non si mente...
El. (abbracciandolo commosso) Padre! padre mio!...

(Aglae piange col volto nelle mani. Elèo vorrebbe dir


qualcosa. Mènecle indovina il suo pensiero e lo previene).

Mèn. Quanto al tuo partire... c'è tempo...


El. (sorpreso) Che?
Mèn. Pelopida... gli ho parlato io. Non ne vuol seco più di undici. (con
inflessione grave e seria) Li ha scelti già... (gesto vivo di protesta di
Elèo) Non temere! Verrà il tuo giorno...
Agl. Oh Mènecle, la tua generosità...
Mèn. No, no, adagio, a parlare di generosità. In questo mondo la si
scambia con la imbecillità; ed io invece, andate là, che i miei conti li
ho fatti bene. Povero vecchio abbisognante, per i miei tardi giorni, di
un affetto che li consoli, dovrei amareggiarmelo col pensiero che il
mio vivere impedisce la vostra felicità? E che questa idea vostro
malgrado si inframmetterà tra me e voi, vi renderà a vostra insaputa
l'affezione a Mènecle un peso? Scambierei questo affetto vostro, così
sincero e così puro, col bel conforto di sapere che il dì quando la
Parca (sorridendo ad Aglae) — la scellerata Parca! — mi farà quel tal
servizio, un sospiro non confessato di sollievo sfuggirà dai petti delle
due sole persone che mi voglion bene? E mentre è sì dolce il nome
di padre, dovrei vivere tutti i dì fra il dolor di non esserlo... e la tema
di divenirlo!... scambiar la paura di avere un figlio con la gioia
tranquilla di lasciarne, partendo, qui... due?
El., Agl. (vivissimamente) Partendo?
Mèn. (ad Aglae con voce affettuosa) Non sei più sola... Che resto a
far qui? Ricordi le tue parole? «Quando fu il dì del bisogno, ci vollero
questi vecchioni per liberare la città e le sue donne!» Laggiù a Tebe
ci è bisogno. (con inflessione mesta, solenne, ai due giovani che fan
per trattenerlo e lo guardano attoniti, commossi) Ci vogliono
questi!... Vivere liberando donne, morire liberando città!

(Quadro).

CALA LA TELA.
NOTE

204.
Dopo che il tebano Pelopida ebbe persuasi i suoi compagni
di esilio all'impresa di partirsi da Atene per muovere alla
liberazione di Tebe «mandaron essi nascostamente a Tebe
ad avvertire dei loro disegni gli amici ch'eran ivi rimasti:
tra questi Carone ed Epaminonda..... Stabilitosi quindi il
giorno dell'impresa, parve bene ai profughi che l'un d'essi,
Ferenico, raccogliendo gli altri, facesse sosta in Triasio, e
che pochi de' più giovani arditamente si arrischiassero di
entrare in città: e se a questi incogliesse mai qualche
sinistro dalla parte de' nemici, gli altri tutti aver cura
dovessero de' figliuoli e de' padri loro. Il primo che si esibì
ad andarci fu Pelopida, e poi Melone e Dàmocle e
Teopompo, stretti fra loro co' vincoli d'amicizia e di fede,
ed emuli sempre della gloria e del valore. Essendo dodici
in tutto, dopo aver abbracciato quelli che restavano
addietro, e mandato innanzi un messo a Carone, si
incamminarono succintamente vestiti... ecc. ecc.»
Plutarco, in Pelopida.

205.
Cfr. nell'arringa di Lisia per la uccision di Eratostene, il
racconto del marito Eufileto: «Tornato a casa, ordinai alla
fantesca di seguirmi in piazza; e condottala ad uno de'
miei famigliari, le dissi che sapevo tutto quel che
succedeva in casa mia. A te, quindi, soggiungevo, sta lo
sceglier fra i due: o passata per le verghe esser
condannata a rigirar la mola, tra patimenti senza fine, o
confessando la verità andar illesa, e aver da me il perdono
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like