3.11. Structures

 < Day Day Up > 

A .NET structure struct in C# syntax is often described as a lightweight class. It is similar to a class in that its members include fields, methods, properties, events, and constructors; and it can inherit from interfaces. But there are also implementation differences and restrictions that limit its capabilities vis-à-vis a class:

  • A struct is a value type. It implicitly inherits from the System.ValueType.

  • A struct cannot inherit from classes, nor can it be inherited.

  • An explicitly declared constructor must have at least one parameter.

  • struct members cannot have initializers. The field members must be initialized by the constructor or the client code that creates the constructor.

Because a struct is a value type, it is stored on the stack where a program works directly with its contents. This generally provides quicker access than indirectly accessing data through a pointer to the heap. On the downside, structs can slow things down when passed back and forth as parameters. Rather than passing a reference, the CLR copies a struct and sends the copy to the receiving method. Also, a struct faces the boxing and unboxing issue of value types.

When deciding whether to use a struct to represent your data, consider the fact that types that naturally have value semantics (objects that directly contain their value as opposed to a reference to a value) are often implemented underneath as a struct. Examples include the primitives discussed in Chapter 2, the color structure whose properties (red, aqua, and so on) define colors in .NET, the DateTime structure used for date-related operations, and various graphics structures used to represent objects such as points and rectangles.

Defining Structures


 [attribute][modifier] struct identifier [:interfaces] {struct-body} 


 public struct DressShirt {    public float CollarSz;    public int SleeveLn;    // constructor    public DressShirt(float collar, int sleeve)    {       this.CollarSz = collar;       this.SleeveLn = sleeve;    } } 

The syntax clearly resembles a class. In fact, replace struct with class and the code compiles. It has a public modifier that permits access from any assembly. The default modifier is internal, which restricts access to the containing assembly. No interfaces are specified although a struct can inherit from an interface so the struct is not required to implement any specific methods.

Core Note

It is possible to specify the layout of a struct's fields in memory using the StructLayout attribute. This is most commonly used when the struct is to be accessed by unmanaged code that expects a specific physical layout of the data. By default, the fields in a struct are stored in sequential memory locations.

An instance of the structure can be created in two ways:

 DressShirt dShirt = new DressShirt(16, 33); DressShirt myShirt = new DressShirt(); myShirt.CollarSz = 16.5F; myShirt.SleeveLn = 33; 

The first statement creates an instance that relies on the user-defined constructor to initialize the field values. When designing such a constructor, be aware that you must initialize all fields within the constructor; otherwise, the compiler will issue an error.

The second statement also creates an instance of the struct by calling the default constructor, which initializes the fields to default values of zero (0). Note the difference here between a struct and a class: A struct always has a default parameterless constructor; a class has the default parameterless constructor only if there are no explicitly defined constructors.

Using Methods and Properties with a Structure

Methods and properties are usually associated with classes, but they play an equally important role in the use of structures. In fact, a client accessing a method has no syntactical clue as to whether the method or property is associated with a class or struct. Listing 3-17 extends the original example to add two properties and a method.

Listing 3-17. Basic Elements of a Struct
 public struct DressShirt {    private float CollarSz;    private int SleeveLn;    public DressShirt(float collar, int sleeve)    {       this.CollarSz = collar;       this.SleeveLn = sleeve;    }    // Properties to return sleeve and collar values    public int Sleeve    {       get {return (SleeveLn);}       set {SleeveLn = value;}    }    public float Collar    {       get {return (CollarSz); }       // "value" is an implicit parameter       set {CollarSz = value;   }    }    // Method to convert size to different scale    public string ShirtSize()    {       string mySize = "S";       if (CollarSz > 14.5) mySize = "M";       if (CollarSz > 15.5) mySize = "L";       if (CollarSz > 16.5) mySize = "XL";       return (mySize);    } } 

The most important thing to note about this code is that it could be cut and pasted into a class and run with no changes. Although a struct doesn't support all of the features of a class, the ones it does are implemented using identical syntax.

     < Day Day Up > 

    Core C# and  .NET
    Core C# and .NET
    ISBN: 131472275
    EAN: N/A
    Year: 2005
    Pages: 219

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net