
- •New to the Tenth Edition
- •Preface
- •Acknowledgments
- •About the Author
- •Contents
- •1.1 Reasons for Studying Concepts of Programming Languages
- •1.2 Programming Domains
- •1.3 Language Evaluation Criteria
- •1.4 Influences on Language Design
- •1.5 Language Categories
- •1.6 Language Design Trade-Offs
- •1.7 Implementation Methods
- •1.8 Programming Environments
- •Summary
- •Problem Set
- •2.1 Zuse’s Plankalkül
- •2.2 Pseudocodes
- •2.3 The IBM 704 and Fortran
- •2.4 Functional Programming: LISP
- •2.5 The First Step Toward Sophistication: ALGOL 60
- •2.6 Computerizing Business Records: COBOL
- •2.7 The Beginnings of Timesharing: BASIC
- •2.8 Everything for Everybody: PL/I
- •2.9 Two Early Dynamic Languages: APL and SNOBOL
- •2.10 The Beginnings of Data Abstraction: SIMULA 67
- •2.11 Orthogonal Design: ALGOL 68
- •2.12 Some Early Descendants of the ALGOLs
- •2.13 Programming Based on Logic: Prolog
- •2.14 History’s Largest Design Effort: Ada
- •2.15 Object-Oriented Programming: Smalltalk
- •2.16 Combining Imperative and Object-Oriented Features: C++
- •2.17 An Imperative-Based Object-Oriented Language: Java
- •2.18 Scripting Languages
- •2.19 The Flagship .NET Language: C#
- •2.20 Markup/Programming Hybrid Languages
- •Review Questions
- •Problem Set
- •Programming Exercises
- •3.1 Introduction
- •3.2 The General Problem of Describing Syntax
- •3.3 Formal Methods of Describing Syntax
- •3.4 Attribute Grammars
- •3.5 Describing the Meanings of Programs: Dynamic Semantics
- •Bibliographic Notes
- •Problem Set
- •4.1 Introduction
- •4.2 Lexical Analysis
- •4.3 The Parsing Problem
- •4.4 Recursive-Descent Parsing
- •4.5 Bottom-Up Parsing
- •Summary
- •Review Questions
- •Programming Exercises
- •5.1 Introduction
- •5.2 Names
- •5.3 Variables
- •5.4 The Concept of Binding
- •5.5 Scope
- •5.6 Scope and Lifetime
- •5.7 Referencing Environments
- •5.8 Named Constants
- •Review Questions
- •6.1 Introduction
- •6.2 Primitive Data Types
- •6.3 Character String Types
- •6.4 User-Defined Ordinal Types
- •6.5 Array Types
- •6.6 Associative Arrays
- •6.7 Record Types
- •6.8 Tuple Types
- •6.9 List Types
- •6.10 Union Types
- •6.11 Pointer and Reference Types
- •6.12 Type Checking
- •6.13 Strong Typing
- •6.14 Type Equivalence
- •6.15 Theory and Data Types
- •Bibliographic Notes
- •Programming Exercises
- •7.1 Introduction
- •7.2 Arithmetic Expressions
- •7.3 Overloaded Operators
- •7.4 Type Conversions
- •7.5 Relational and Boolean Expressions
- •7.6 Short-Circuit Evaluation
- •7.7 Assignment Statements
- •7.8 Mixed-Mode Assignment
- •Summary
- •Problem Set
- •Programming Exercises
- •8.1 Introduction
- •8.2 Selection Statements
- •8.3 Iterative Statements
- •8.4 Unconditional Branching
- •8.5 Guarded Commands
- •8.6 Conclusions
- •Programming Exercises
- •9.1 Introduction
- •9.2 Fundamentals of Subprograms
- •9.3 Design Issues for Subprograms
- •9.4 Local Referencing Environments
- •9.5 Parameter-Passing Methods
- •9.6 Parameters That Are Subprograms
- •9.7 Calling Subprograms Indirectly
- •9.8 Overloaded Subprograms
- •9.9 Generic Subprograms
- •9.10 Design Issues for Functions
- •9.11 User-Defined Overloaded Operators
- •9.12 Closures
- •9.13 Coroutines
- •Summary
- •Programming Exercises
- •10.1 The General Semantics of Calls and Returns
- •10.2 Implementing “Simple” Subprograms
- •10.3 Implementing Subprograms with Stack-Dynamic Local Variables
- •10.4 Nested Subprograms
- •10.5 Blocks
- •10.6 Implementing Dynamic Scoping
- •Problem Set
- •Programming Exercises
- •11.1 The Concept of Abstraction
- •11.2 Introduction to Data Abstraction
- •11.3 Design Issues for Abstract Data Types
- •11.4 Language Examples
- •11.5 Parameterized Abstract Data Types
- •11.6 Encapsulation Constructs
- •11.7 Naming Encapsulations
- •Summary
- •Review Questions
- •Programming Exercises
- •12.1 Introduction
- •12.2 Object-Oriented Programming
- •12.3 Design Issues for Object-Oriented Languages
- •12.4 Support for Object-Oriented Programming in Smalltalk
- •12.5 Support for Object-Oriented Programming in C++
- •12.6 Support for Object-Oriented Programming in Objective-C
- •12.7 Support for Object-Oriented Programming in Java
- •12.8 Support for Object-Oriented Programming in C#
- •12.9 Support for Object-Oriented Programming in Ada 95
- •12.10 Support for Object-Oriented Programming in Ruby
- •12.11 Implementation of Object-Oriented Constructs
- •Summary
- •Programming Exercises
- •13.1 Introduction
- •13.2 Introduction to Subprogram-Level Concurrency
- •13.3 Semaphores
- •13.4 Monitors
- •13.5 Message Passing
- •13.6 Ada Support for Concurrency
- •13.7 Java Threads
- •13.8 C# Threads
- •13.9 Concurrency in Functional Languages
- •13.10 Statement-Level Concurrency
- •Summary
- •Review Questions
- •Problem Set
- •14.1 Introduction to Exception Handling
- •14.2 Exception Handling in Ada
- •14.3 Exception Handling in C++
- •14.4 Exception Handling in Java
- •14.5 Introduction to Event Handling
- •14.6 Event Handling with Java
- •14.7 Event Handling in C#
- •Review Questions
- •Problem Set
- •15.1 Introduction
- •15.2 Mathematical Functions
- •15.3 Fundamentals of Functional Programming Languages
- •15.4 The First Functional Programming Language: LISP
- •15.5 An Introduction to Scheme
- •15.6 Common LISP
- •15.8 Haskell
- •15.10 Support for Functional Programming in Primarily Imperative Languages
- •15.11 A Comparison of Functional and Imperative Languages
- •Review Questions
- •Problem Set
- •16.1 Introduction
- •16.2 A Brief Introduction to Predicate Calculus
- •16.3 Predicate Calculus and Proving Theorems
- •16.4 An Overview of Logic Programming
- •16.5 The Origins of Prolog
- •16.6 The Basic Elements of Prolog
- •16.7 Deficiencies of Prolog
- •16.8 Applications of Logic Programming
- •Review Questions
- •Programming Exercises
- •Bibliography
- •Index

14.7 Event Handling in C# |
661 |
14.7 Event Handling in C#
Event handling in C# (and in the other .NET languages) is similar to that of Java. .NET provides two approaches to creating GUIs in applications, the original Windows Forms and the more recent Windows Presentation Foundation. The latter is the more sophisticated and complex of the two. Because our interest is just in event handling, we will use the simpler Windows Forms to discuss our subject.
Using Windows Forms, a C# application that constructs a GUI is created by subclassing the Form predefined class, which is defined in the System.Windows
.Forms namespace. This class implicitly provides a window to contain our components. There is no need to build frames or panels explicitly.
Text can be placed in a Label object and radio buttons are objects of the RadioButton class. The size of a Label object is not explicitly specified in the constructor; rather it can be specified by setting the AutoSize data member of the Label object to true, which sets the size according to what is placed in it.
Components can be placed at a particular location in the window by assigning a new Point object to the Location property of the component. The Point class is defined in the System.Drawing namespace. The Point constructor takes two parameters, which are the coordinates of the object in pixels. For example, Point(100, 200) is a position that is 100 pixels from the left edge of the window and 200 pixels from the top. The label of a component is set by assigning a string literal to the Text property of the component. After creating a component, it is added to the form window by sending it to the Add method of the Controls subclass of the form. Therefore, the following code creates a radio button with the label Plain at the (100, 300) position in the output window:
private RadioButton plain = new RadioButton();
plain.Location = new Point(100, 300);
plain.Text = "Plain";
Controls.Add(plain);
All C# event handlers have the same protocol: the return type is void and the two parameters are of types object and EventArgs. Neither of the parameters needs to be used for a simple situation. An event handler method can have any name. A radio button is tested to determine whether it is clicked with the Boolean Checked property of the button. Consider the following skeletal example of an event handler:
private void rb_CheckedChanged (object o, EventArgs e){
if (plain.Checked) ...
...
}

662 |
Chapter 14 Exception Handling and Event Handling |
To register an event, a new EventHandler object must be created. The constructor for this class is sent the name of the handler method. The new object is added to the predefined delegate for the event on the component object (using the += assignment operator). For example, when a radio button changes from unchecked to checked, the CheckedChanged event is raised and the handlers registered on the associated delegate, which is referenced by the name of the event, are called. If the event handler is named rb_CheckedChanged, the following statement would register the handler for the CheckedChanged event on the radio button plain:
plain.CheckedChanged +=
new EventHandler(rb_CheckedChanged);
Following is the RadioB example from Section 14.6 rewritten in C#. Once again, because our focus is on event handling, we do not explain all of the details of the program.
//RadioB.cs
//An example to illustrate event handling with
//interactive radio buttons that control the font
//style of a string of text
namespace RadioB {
using System;
using System.Drawing;
using System.Windows.Forms;
public class RadioB : Form { private Label text = new Label();
private RadioButton plain = new RadioButton(); private RadioButton bold = new RadioButton(); private RadioButton italic = new RadioButton(); private RadioButton boldItalic = new RadioButton();
// Constructor for RadioB public RadioB() {
//Initialize the attributes of the text and radio
//buttons
text.AutoSize = true;
text.Text = "In what font style should I appear?"; plain.Location = new Point(220,0);
plain.Text = "Plain"; plain.Checked = true; bold.Location = new Point(350, 0);

14.7 Event Handling in C# |
663 |
bold.Text = "Bold";
italic.Location = new Point(480, 0);
italic.Text = "Italics";
boldItalic.Location = new Point(610, 0);
boldItalic.Text = "Bold/Italics";
//Add the text and the radio buttons to the form Controls.Add(text);
Controls.Add(plain);
Controls.Add(bold);
Controls.Add(italic);
Controls.Add(boldItalic);
//Register the event handler for the radio buttons plain.CheckedChanged +=
new EventHandler(rb_CheckedChanged); bold.CheckedChanged +=
new EventHandler(rb_CheckedChanged); italic.CheckedChanged +=
new EventHandler(rb_CheckedChanged); boldItalic.CheckedChanged +=
new EventHandler(rb_CheckedChanged);
}
// The main method is where execution begins static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault
(false); Application.Run(new RadioB());
}
// The event handler
private void rb_CheckedChanged (object o,
EventArgs e) {
//Determine which button is on and set the font
//accordingly
if (plain.Checked)
text.Font =
new Font(text.Font.Name, text.Font.Size,
FontStyle.Regular);
if (bold.Checked)
text.Font =

664 |
Chapter 14 Exception Handling and Event Handling |
new Font(text.Font.Name, text.Font.Size, FontStyle.Bold);
if (italic.Checked) text.Font =
new Font(text.Font.Name, text.Font.Size, FontStyle.Italic);
if (boldItalic.Checked) text.Font =
new Font(text.Font.Name, text.Font.Size, FontStyle.Italic ^ FontStyle.Bold);
} // End of radioButton_CheckedChanged
}// End of RadioB
}
The output from this program is exactly like that shown in Figure 14.2.
S U M M A R Y
Most widely used programming languages now include exception handling. Ada provides extensive exception-handling facilities and a small but com-
prehensive collection of built-in exceptions. The handlers are attached to the program entities, although exceptions can be implicitly or explicitly propagated to other program entities if no local handler is available.
C++ includes no predefined exceptions (except those defined in the standard library). C++ exceptions are objects of a primitive type, a predefined class, or a user-defined class. Exceptions are bound to handlers by connecting the type of the expression in the throw statement to that of the formal parameter of the handler. Handlers all have the same name—catch. The C++ throw clause of a method lists the types of exceptions that the method could throw.
Java exceptions are objects whose ancestry must trace back to a class that descends from the Throwable class. There are two categories of exceptions— checked and unchecked. Checked exceptions are a concern for the user program and the compiler. Unchecked exceptions can occur anywhere and are often ignored by user programs.
The Java throws clause of a method lists the checked exceptions that it could throw and does not handle. It must include exceptions that methods it calls could raise and propagate back to its caller.
The Java finally clause provides a mechanism for guaranteeing that some code will be executed regardless of how the execution of a try compound terminates.
Java now includes an assert statement, which facilitates defensive programming.