A struct
is
a simple user-defined type, a lightweight alternative to classes.
Structs are similar to classes in that they may contain structors,
properties, methods, fields, operators, nested types and indexers
(see Chapter 9).
There are also significant differences between classes and structs. For instance, structs don’t support inheritance or destructors. More important, although a class is a reference type, a struct is a value type. (See Chapter 3 for more information about classes and types.) Thus, structs are useful for representing objects that do not require reference semantics.
The consensus view is that you ought to use structs only for types that are small, simple, and similar in their behavior and characteristics to built-in types.
Structs are somewhat more efficient in their use of memory in arrays (see Chapter 9). However, they can be less efficient when used in collections. Collections expect references, and structs must be boxed. There is overhead in boxing and unboxing, and classes might be more efficient in large collections.
In this chapter, you will learn how to define and work with structs and how to use constructors to initialize their values.
The syntax for declaring a struct is almost identical to that for a class:
[attributes] [access-modifiers
] structidentifier [:interface-list]
{ struct-members
}
Example 7-1 illustrates the definition of a struct.
Location
represents a point on a two-dimensional
surface. Notice that the struct
Location
is declared exactly as a class would be,
except for the use of the keyword
struct
. Also notice that the
Location
constructor takes two integers and
assigns their value to the instance members, x
and
y
. The x
and
y
coordinates of Location
are
declared as properties.
Example 7-1. Creating a struct
using System;
public struct Location
{
public Location(int xCoordinate, int yCoordinate)
{
xVal = xCoordinate;
yVal = yCoordinate;
}
public int x
{
get
{
return xVal;
}
set
{
xVal = value;
}
}
public int y
{
get
{
return yVal;
}
set
{
yVal = value;
}
}
public override string ToString( )
{
return (String.Format("{0}, {1}", xVal,yVal));
}
private int xVal;
private int yVal;
}
public class Tester
{
public void myFunc(Location loc)
{
loc.x = 50;
loc.y = 100;
Console.WriteLine("Loc1 location: {0}", loc);
}
static void Main( )
{
Location loc1 = new Location(200,300);
Console.WriteLine("Loc1 location: {0}", loc1);
Tester t = new Tester( );
t.myFunc(loc1);
Console.WriteLine("Loc1 location: {0}", loc1);
}
}
Output
Loc1 location: 200, 300
In MyFunc loc: 50, 100
Loc1 location: 200, 300
Unlike classes, structs do not support
inheritance. They implicitly derive
from object (as do all types in C#, including the built-in types) but
cannot inherit from any other class or struct. Structs are also
implicitly sealed
(that is, no class or struct can derive
from a struct). Like classes, however, structs can implement multiple
interfaces. Additional differences include the following:
Structs cannot have destructors, nor can they have a custom parameterless (default) constructor. If you supply no constructor at all, your struct will in effect be provided with a default constructor which will zero all the data members or set them to default values appropriate to their type (see Table 4-2). If you supply any constructor, you must initialize all the fields in the struct.
Structs are designed to be simple and lightweight. While private member data promotes data hiding and encapsulation, some programmers feel it is overkill for structs. They make the member data public, thus simplifying the implementation of the struct. Other programmers feel that properties provide a clean and simple interface, and that good programming practice demands data hiding even with simple lightweight objects. Which you choose is a matter of design philosophy; the language will support either approach.
3.15.14.98