274
LESSON 23 Defining Classes
code asserts that the new value is between 0 and 359 degrees. The program can continue correctly if
the value is outside of this range so the code uses
Debug.Assert instead of throwing an exception.
// The Turtle’s direction in degrees.
private int direction = 0; // Backing field.
public int Direction
{
get { return direction; }
//set { direction = value; }
set
{
Debug.Assert((value >= 0) && (value <= 359),
“Direction should be between 0 and 359 degrees”);
direction = value;
}
}
Property accessors also give you a place to set break-
points if something is going wrong. For example, if
you know that some part of your program is setting
a
Turtle’s Direction to 45 when it should be set-
ting it to 60 but you don’t know where, you could set
a breakpoint in the
set accessor to see where the
change is taking place.
TRY IT
In this first Try It in the lesson, you cre-
ate a simple
Person class with FirstName,
LastName, City, Street, and Zip properties,
some having simple validations. You also build
a simple test application shown in Figure 23-1.
You can download the code and resources for this Try It from the book’s web
page at
www.wrox.com or www.CSharpHelper.com/24hour.html. You can find
them in the TryIt23a folder in the Lesson23 folder of the download.
Lesson Requirements
Build the program shown in Figure 23-1.
Create a
Person class.
Make auto-implemented properties for
Street, City, State, and Zip.
For this application, assume that setting
FirstName or LastName to a blank string is an error
and add validation code to their property accessors.
FIGURE 231
596906c23.indd 274 4/7/10 12:33:45 PM
Click here to Play
Try It
275
Hints
Also, don’t allow first or last to be set to null, which is different from setting them
equal to blank strings. If you don’t check for these, the other code in the accessors will
throw an error anyway, but if you check yourself, then you can provide a more meaning-
ful exception.
Step-by-Step
Build the program shown in Figure 23-1.
1. This is reasonably straightforward.
Create a
Person class.
1. Use the Project menu’s Add Class item. Name the class Person.
Make auto-implemented properties for
Street, City, State, and Zip.
1. You can use code similar to the following:
// Auto-implemented properties.
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
For this application, assume that setting
FirstName or LastName to a blank string is an error
and add validation code to their property accessors.
1. The following code shows how you might implement the FirstName property. The
code for the
LastName property is similar.
// FirstName property.
private string rstName = “”;
public string FirstName
{
get
{
return rstName;
}
set
{
if (value == null)
throw new ArgumentOutOfRangeException(“FirstName”,
“Person.FirstName cannot be null.”);
if (value.Length < 1)
throw new ArgumentOutOfRangeException(“FirstName”,
“Person.FirstName cannot be blank.”);
}
}
596906c23.indd 275 4/7/10 12:33:46 PM
276
LESSON 23 Defining Classes
METHODS
A method is simply a piece of code in the class that other parts of the program can execute. The
following method shows how the
Turtle class might implement its Move method:
// Make the Turtle move the indicated distance
// in its current direction.
public void Move(int distance)
{
// Calculate the new position.
double radians = Direction * Math.PI / 180;
int newX = (int)(X + Math.Cos(radians) * distance);
int newY = (int)(Y + Math.Sin(radians) * distance);
// Draw to the new position.
using (Graphics gr = Graphics.FromImage(Canvas))
{
gr.DrawLine(Pens.Blue, X, Y, newX, newY);
}
// Save the new position.
X = newX;
Y = newY;
}
The method takes as a parameter the distance it should move. It uses the Turtles current position
and direction to figure out where this move will finish. It uses some graphics code to draw a line
from the current position to the new one (don’t worry about the details) and finishes by saving the
new position.
EVENTS
Events let the class tell the rest of the program that something interesting is happening. For example,
if a
BankAccount object’s balance falls below 0, it could raise an AccountOverdrawn event to notify
the main program.
Declaring an event in C# is a bit tricky because you first need to understand delegates.
Delegates
A delegate is a data type that can hold a specific kind of method. For example, you could make a
delegate type that represents methods that take no parameters and return a
double. You could then
declare a variable of that type and save a method in it.
Confusing? You bet!
The key to understanding delegates is to remember that a delegate type is a new data type just like
a
string or int. The difference is that a variable with a delegate type holds a method, not a simple
value like “Hello” or 27.
596906c23.indd 276 4/7/10 12:33:46 PM
Events
277
Example program Delegates, which is part of this lesson’s download on the book’s web site, provides
a simple example. The program uses four steps to demonstrate delegates: declare the delegate type,
create variables of that type, initialize the variables, and use the variables’ values.
First the program declares a delegate type:
// Define a delegate type that takes no parameters and returns nothing.
private delegate void DoSomethingMethod();
The declaration begins with the accessibility keyword private and then the keyword delegate to
tell C# that it is defining a delegate type. The rest of the declaration gives the delegate type’s name
DoSomethingFunction. It also indicates that instances of this type must refer to methods that
return nothing (
void) and take no parameters.
Now that it has defined the delegate type, the code declares three fields of that type. Each of the
variables can hold a reference to a method that takes no parameters and returns nothing:
// Declare three DoSomethingMethod variables.
private DoSomethingMethod method1, method2, method3;
Next the program defines two methods that match the delegate’s definition:
// Define some methods that have the delegate’s type.
private void SayHi()
{
MessageBox.Show(“Hi”);
}
private void SayClicked()
{
MessageBox.Show(“Clicked”);
}
When the program starts, it sets the values of the fields method1, method2, and method3 so they
point to these two methods. Notice that the code makes
method1 and method3 point to the same
method,
SayHi.
// Initialize the delegate variables.
private void Form1_Load(object sender, EventArgs e)
{
method1 = SayHi;
method2 = SayClicked;
method3 = SayHi;
}
At this point, the program has defined the delegate type, created three variables of that type, and
initialized those variables so they refer to the
SayHi and SayClicked methods. The program is
ready to use the variables.
This program displays three buttons. When you click them, the following event handlers execute.
Each button simply invokes the method referred to by one of the delegate variables.
// Invoke the method stored in the delegates.
private void method1Button_Click(object sender, EventArgs e)
{
method1();
596906c23.indd 277 4/7/10 12:33:46 PM
278
LESSON 23 Defining Classes
}
private void method2Button_Click(object sender, EventArgs e)
{
method2();
}
private void method3Button_Click(object sender, EventArgs e)
{
method3();
}
This isnt an extremely practical program, and it’s hard to imagine a situation where you would just
want buttons to invoke different delegate instances. This example is just much simpler than many
that use delegates.
Event Handler Delegates
Now that you know a bit about delegates, you can learn how to use them to make an event.
First, in the class that will raise the event, declare a delegate type to define the event handler. Usually
developers end the delegate’s name with
EventHandler to make it obvious what the delegate represents.
By convention, event handlers usually take two parameters named
sender and e. The sender param-
eter is an object that contains a reference to whatever
object is raising the event. The e parameter con-
tains data specific to the event.
The
Turtle class’s OutOfBounds event passes its event handlers an object of type
TurtleOutOfBoundsEventArgs to give them extra information. The following code shows how
the
Turtle class defines this class.
// The TurtleOutOfBoundsEventArgs data type.
public class TurtleOutOfBoundsEventArgs
{
// Where the Turtle would stop if
// this were not out of bounds.
public int X { get; set; }
public int Y { get; set; }
};
The following code shows how the Turtle class declares its OutOfBoundsEventHandler delegate:
// Declare the OutOfBound event’s delegate.
public delegate void OutOfBoundsEventHandler(
object sender, TurtleOutOfBoundsEventArgs e);
Next the class must declare the actual event to tell C# that the class will provide this event. The declara-
tion should begin with an accessibility keyword (
public, private, and so on) followed by the keyword
event. Next it should give the event handler’s delegate type. It finishes with the events name.
The following code declares the
OutOfBounds event, which is handled by event handlers of type
OutOfBoundsEventHandler:
// Declare the OutOfBounds event.
public event OutOfBoundsEventHandler OutOfBounds;
596906c23.indd 278 4/7/10 12:33:46 PM
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.234.24