Defining a Struct


Defining a new value type with the struct keyword is nearly identical to defining a new class as indicated in Syntax Box 18.1; you simply need to substitute the class keyword with the struct keyword.

Syntax Box 18.1 The struct Definition

 [<Acess_modifier>] struct <Struct_identifier> [: <Interface_list>] graphics/ccc.gif {     <Struct_members> } 

Recall our TimeSpan class from Chapter 14, "Class Anatomy III: Writing Intuitive Code." It was represented with a class because we hadn't yet introduced structs at that point. However, it would be more effectively represented by a struct in most cases. This struct alternative is shown in lines 3 40 of Listing 18.1.

Listing 18.1 TimeSpanStruct.cs
01: using System; 02: 03: public struct TimeSpan 04: { 05:     private uint totalSeconds; 06:     private const uint SecondsInHour = 3600; 07:     private const uint SecondsInMinute = 60; 08: 09:     public TimeSpan(uint initialSeconds) 10:     { 11:         totalSeconds = initialSeconds; 12:     } 13: 14:     public uint Seconds 15:     { 16:         get 17:         { 18:             return totalSeconds; 19:         } 20: 21:         set 22:         { 23:             totalSeconds = value; 24:         } 25:     } 26: 27:     public override string ToString() 28:     { 29:         uint hours; 30:         uint minutes; 31:         uint seconds; 32: 33:         hours = totalSeconds / SecondsInHour; 34:         minutes = (totalSeconds % SecondsInHour) / SecondsInMinute; 35:         seconds = (totalSeconds % SecondsInHour) % SecondsInMinute; 36: 37:         return String.Format("{0}  Hrs {1}  Mins {2}  Secs", 38:             hours, minutes, seconds); 39:     } 40: } 41:  42: class Tester 43: { 44:     public static void Main() 45:     { 46:         TimeSpan myTime = new TimeSpan(43403); 47:         TimeSpan yourTime = new TimeSpan(); 48: 49:         Console.WriteLine("My time: " + myTime); 50:         Console.WriteLine("Your first time: " + yourTime); 51:         yourTime.Seconds = 310; 52:         Console.WriteLine("Your second time: " + yourTime); 53:     } 54: } My time: 12 Hrs 3 Mins 23 Secs Your first time: 0 Hrs 0 Mins 0 Secs Your second time: 0 Hrs 5 Mins 10 Secs 

Overall, the class and the struct versions of TimeSpan look very much alike except that the class keyword has been exchanged with the struct keyword in line 3. However, as this analysis reveals, there are a few more or less obvious differences to the class version.

There is no explicit default (parameter-less) constructor defined because structs can only contain explicit constructors with at least one parameter, as in lines 9 12.

A struct is automatically equipped with a default constructor that initializes all data members to their default initialization values (an int is initialized to zero, a bool to false, and so forth). This is demonstrated in line 47, which calls TimeSpan's default implicit constructor and assigns the new struct to yourTime. This results in totalSeconds being assigned the value zero, as shown in the sample output.

Constants can be initialized, as in lines 6 and 7. However, it is not possible to combine declaration and initialization statements for instance variables. For example, if we had exchanged line 5 with the following line:

 private uint totalSeconds = 0; 

we would have encountered a compiler error.

Any explicit constructor we write must initialize all the struct's data members. In this case, we only need line 11 to perform this task.

Even though structs generally cannot inherit from other structs and classes, any struct is implicitly derived from System.Object and inherits the members from this ultimate base class, which was presented in Chapter 17, "Inheritance Part II: Abstract Functions, Polymorphism, and Interfaces." Consequently, it is possible to override System.Object's ToString method (lines 27 39) and let WriteLine call this method as part of executing lines 49 and 50.

In line 49, we are clearly passing the value type myTime to WriteLine. However, WriteLine is only able to process reference types, not value types like myTime. How is this apparent contradiction possible? C# has a built-in mechanism by which a value type is boxed into a corresponding reference type based object (box), which can then be processed by WriteLine. Due to the box metaphor, this mechanism is referred to as boxing in C# terminology. Boxing, along with the reverse process called unboxing, are discussed in more detail in a moment.



To keep their structs as simple as possible, some programmers abolish the encapsulation rules we have abided by and declare the data members of the struct public. This permits direct access to these data members and allows the programmers to free the struct of the properties and methods that would otherwise have been needed to access these data members. This might be a legitimate design avenue to follow and is supported by C#. An example of a struct with a public data member is provided in Listing 18.3, presented later in this chapter.


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: