Now that you understand the role of enumeration types, let’s examine the use of .NET structures (or
simply structs). Structure types are well suited for modeling mathematical, geometrical, and other
“atomic” entities in your application. A structure (like an enumeration) is a user-defined type; however,
structures are not simply a collection of name/value pairs. Rather, structures are types that can
contain any number of data fields and members that operate on these fields.
Furthermore, structures can define constructors, can implement interfaces, and can contain
any number of properties, methods, events, and overloaded operators. (If some of these terms are
unfamiliar at this point, don’t fret. All of these topics are fully examined in chapters to come.)
nNote If you have a background in OOP, you can think of a structure as a “lightweight class type,” given that
structures provide a way to define a type that supports encapsulation, but cannot be used to build a family of
related types (as structures are implicitly sealed). When you need to build a family of related types through inheritance,
you will need to make use of class types.
On the surface, the process of defining and using structures is very simple, but as they say, the
devil is in the details. To begin understanding the basics of structure types, create a new project
named FunWithStructures. In C#, structures are created using the struct keyword. Define a new
structure named Point, which defines two member variables of type int and a set of methods to
interact with said data:
struct Point
{
// Fields of the structure.
public int X;
public int Y;
// Add 1 to the (X, Y) position.
public void Increment()
{
X++; Y++;
}
// Subtract 1 from the (X, Y) position.
public void Decrement()
{
X--; Y--;
}
// Display the current position.
public void Display()
126 CHAPTER 4 n CORE C# PROGRAMMING CONSTRUCTS, PART II
{
Console.WriteLine("X = {0}, Y = {1}", X, Y);
}
}
Here, we have defined our two integer data types (X and Y) using the public keyword, which is
an access control modifier (full details in the next chapter). Declaring data with the public keyword
ensures the caller has direct access to the data from a given Point variable (via the dot operator).
nNote It is typically considered bad style to define public data within a class or structure. Rather, you will want to
define private data, which can be accessed and changed using public properties. These details will be examined in
Chapter 5.
Here is a Main() method that takes our Point type out for a test drive. Figure 4-9 shows the program’s
output.
static void Main(string[] args)
{
Console.WriteLine("***** A First Look at Structures *****");
// Create an initial Point.
Point myPoint;
myPoint.X = 349;
myPoint.Y = 76;
myPoint.Display();
// Adjust the X and Y values.
myPoint.Increment();
myPoint.Display();
Console.ReadLine();
}
Creating Structure Variables
When you wish to create a structure variable, you have a variety of options. Here, we simply create a
Point variable and assign each piece of public field data before invoking its members. If we do not
assign each piece of public field data (X and Y in our case) before making use of the structure, we
will receive a compiler error:
// Error! Did not assign Y value.
Point p1;
p1.X = 10;
p1.Display();
// OK! Both fields assigned before use.
Point p2;
p2.X = 10;
p2.Y = 10;
p2.Display();
As an alternative, we can create structure variables using the C# new keyword, which will invoke
the structure’s default constructor. By definition, a default constructor takes any input parameters.
The benefit of invoking the default constructor of a structure is that each piece of field data is automatically
set to its default value:
// Set all fields to default values
// using the default constructor.
Point p1 = new Point();
// Prints X=0,Y=0
p1.Display();
It is also possible to design a structure with a custom constructor. This allows you to specify the
values of field data upon variable creation, rather than having to set each data member field by
field. Chapter 5 will provide a detailed examination of constructors; however, to illustrate, update
the Point structure with the following code:
struct Point
{
// Fields of the structure.
public int X;
public int Y;
// A custom constructor.
public Point(int XPos, int YPos)
{
X = XPos;
Y = YPos;
}
...
}
With this, we could now create Point types as follows:
// Call custom constructor.
Point p2 = new Point(50, 60);
// Prints X=50,Y=60
p2.Display();
As mentioned, working with structures on the surface is quite simple. However, to deepen your
understanding of this type, we need to explore the distinction between a .NET value type and a
.NET reference type.
Thursday, October 22, 2009
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment