Chapter 12. Structs

What Are Structs?

Structs areprogrammer-defined data types, very similar to classes. They have data members and function members. Althoughsimilar to classes, there are a number of important differences. The most important ones are the following:

  • Classes are reference types and structs are value types.

  • Structs are implicitly sealed, which means that they cannot be derived from.

The syntax for declaring a struct is similar to that of declaring a class.

What Are Structs?

For example, the following code declares a struct named Point. It has two public fields, named X and Y. In Main, three variables of struct type Point are declared, and their values are assigned and printed out.

struct Point
   {
      public int X;
      public int Y;
   }


   class Program
   {
      static void Main()
      {
         Point first, second, third;


         first.X  = 10; first.Y = 10;
         second.X = 20; second.Y = 20;
         third.X  = first.X + second.X;
         third.Y  = first.Y + second.Y;


         Console.WriteLine("first:   {0}, {1}", first.X,  first.Y);
         Console.WriteLine("second:  {0}, {1}", second.X, second.Y);
         Console.WriteLine("third:   {0}, {1}", third.X,  third.Y);
      }
   }

Structs Are Value Types

As with all value types, a variableof a struct type contains its own data. Consequently

  • A variable of a struct type cannot be null.

  • Two structs variables cannot refer to the same object.

For example, the following code declares a class called CSimple, and a struct called Simple, and a variable of each. Figure 12-1 shows how the two would be arranged in memory.

class CSimple
   {
      public int X;
      public int Y;
   }


   struct Simple
   {
      public int X;
      public int Y;
   }


   class Program
   {
      static void Main()
      {
         CSimple cs = new CSimple();
         Simple  ss = new Simple();

            ...
Memory arrangement of a class versus a struct

Figure 12-1. Memory arrangement of a class versus a struct

Assigning to a Struct

Assigning onestruct to another copies the values from one to the other. This is quite different from copying from a class variable, where only the reference is copied.

Figure 12-2 shows the difference between the assignment of a class variable and a struct variable. Notice that after the class assignment, cs2 is pointing at the same object in the heap as cs1. But after the struct assignment, the values of ss2's members are the same as those of ss1.

class CSimple
   { public int X; public int Y; }

   struct Simple
   { public int X; public int Y; }

   class Program
   {
      static void Main()
      {
         CSimple cs1 = new CSimple(), cs2 = null;          // Class instances
         Simple  ss1 = new Simple(),  ss2 = new Simple();  // Struct instances

         cs1.X = ss1.X = 5;                  // Assign 5 to ss1.X and cs1.X
         cs1.Y = ss1.Y = 10;                 // Assign 10 to ss1.Y and cs1.Y

         cs2 = cs1;                          // Assign class instance
         ss2 = ss1;                          // Assign struct instance
      }
   }
Assigning a class variable and a struct variable

Figure 12-2. Assigning a class variable and a struct variable

Constructors and Destructors

Structs can haveinstance and static constructors, but destructors are not allowed.

Instance Constructors

The language implicitly supplies a parameterless constructor for every struct. This constructor sets each of the struct's members to the default value for that type. Value members are set to their default values. Reference members are set to null.

The predefined parameterless constructor exists for every struct—and you cannot delete or redefine it. You can, however, create additional constructors, as long as they have parameters. Notice that this is different from classes. For classes, the compiler will only supply an implicit parameterless constructor if no other constructors are declared.

To call a constructor, including the implicit parameterless constructor, use the new operator. Notice that the new operator is used even though the memory is not allocated from the heap.

For example, the following code declares a simple struct with a constructor that takes two int parameters. Main creates two instances of the struct—one using the implicit parameterless constructor, and the second with the declared two-parameter constructor.

Instance Constructors

You can also create an instance of a struct without using the new operator. If you do this, however, there are some restrictions, which are the following:

  • You cannot use the value of a data member until you have explicitly set it.

  • You cannot call any function member until all the data members have been assigned.

For example, the following code shows two instances of struct Simple created without using the new operator. When there is an attempt to access s1 without explicitly setting the data member values, the compiler produces an error message. There are no problems reading from s2 after assigning values to its members.

Instance Constructors

Static Constructors

As with classes, the static constructors of structs create and initialize the static data members, and cannot reference instance members. Static constructors for structs follow the same rules as those for classes.

A static constructor is called before the first of either of the following two actions:

  • A call to an explicitly declared constructor

  • A reference to a static member of the struct

Summary of Constructors and Destructors

Table 12-1 summarizes the use of constructors and destructors with structs.

Table 12-1. Summary of Constructors and Destructors

Type

Description

Instance constructor (parameterless)

Cannot be declared in the program. An implicit constructor is supplied by the system for all structs. It cannot be deleted or redefined by the program.

Instance constructor (with parameters)

Can be declared in the program.

Static constructor

Can be declared in the program.

Destructor

Cannot bedeclared inthe program. Destructors are not allowed.

Field Initializers Are Not Allowed

Field initializers are not allowed in structs.

Field Initializers Are Not Allowed

Structs Are Sealed

Structs arealways implicitly sealed, and hence, you cannot derive other structs from them.

Since structs do notsupport inheritance, the use of several of the class member modifiers with struct members would not make sense; thus, they cannot be used in their declarations. The modifiers that cannot be used with structs are the following:

  • protected

  • internal

  • abstract

  • virtual

Structs themselves are, underthe covers, derived from System.ValueType, which is derived from object.

The two inheritance-associated keywords you can use with struct members are the new and override modifiers, when creating a member with the same name as a member of base class System.ValueType, from which all structs are derived.

Boxing and Unboxing

As with other valuetype data, if you want to use a struct instance as a reference type object, you must make a boxed copy. Boxing and unboxing are covered in detail in Chapter 18.

Structs As Return Values and Parameters

Structs can be used as return values and parameters.

  • Return value: When a struct is a return value, a copy is created and returned from the function member.

  • Value parameter: When a struct is used as a value parameter, a copy of the actual parameter struct is created. The copy is used in the execution of the method.

  • ref and out parameters: If you use a struct as a ref or out parameter, a reference to the struct is passed into the method so that the data members can be changed.

Additional Information About Structs

Allocatingstructs requires less overhead than creating instances of a class, so using structs instead of classes can sometimes improve performance—but beware of the high costof boxing and unboxing.

Finally, some last things you should know about structs are the following:

  • The predefined simple types (int, short, long, etc.), although considered primitives in .NET and C#, are all actually implemented under the covers in .NET as structs.

  • You can declare partial structs in the same way as partial classes, as described in Chapter 6.

  • Structs, like classes, can implement interfaces, which will be covered in Chapter 17.

..................Content has been hidden....................

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