15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

structs ❘ 81<br />

➤<br />

➤<br />

➤<br />

Structs do not support inheritance.<br />

There are some differences in the way constructors work for structs. In particular, the compiler<br />

always supplies a default no-parameter constructor, which you are not permitted to replace.<br />

With a struct, you can specify how the fields are to be laid out in memory (this is examined in<br />

Chapter 14, “Reflection,” which covers attributes).<br />

Because structs are really intended to group data items together, you’ll sometimes find that most or all of<br />

their fields are declared as public. This is, strictly speaking, contrary to the guidelines for writing .<strong>NET</strong><br />

code — according to Microsoft, fields (other than const fields) should always be private <strong>and</strong> wrapped by<br />

public properties. However, for simple structs, many developers would nevertheless consider public fields to<br />

be acceptable programming practice.<br />

The following sections look at some of these differences between structs <strong>and</strong> classes in more detail.<br />

structs are Value Types<br />

Although structs are value types, you can often treat them syntactically in the same way as classes. For<br />

example, with the definition of the Dimensions class in the previous section, you could write:<br />

Dimensions point = new Dimensions();<br />

point.Length = 3;<br />

point.Width = 6;<br />

Note that because structs are value types, the new operator does not work in the same way as it does for<br />

classes <strong>and</strong> other reference types. Instead of allocating memory on the heap, the new operator simply calls<br />

the appropriate constructor, according to the parameters passed to it, initializing all fields. Indeed, for<br />

structs it is perfectly legal to write:<br />

Dimensions point;<br />

point.Length = 3;<br />

point.Width = 6;<br />

If Dimensions was a class, this would produce a compilation error, because point would contain an<br />

uninitialized reference — an address that points nowhere, so you could not start setting values to its fields.<br />

For a struct, however, the variable declaration actually allocates space on the stack for the entire struct, so<br />

it’s ready to assign values to. Note, however, that the following code would cause a compilation error, with<br />

the compiler complaining that you are using an uninitialized variable:<br />

Dimensions point;<br />

Double D = point.Length;<br />

Structs follow the same rules as any other data type — everything must be initialized before use. A struct is<br />

considered fully initialized either when the new operator has been called against it, or when values have been<br />

individually assigned to all its fields. And of course, a struct defined as a member field of a class is initialized<br />

by being zeroed-out automatically when the containing object is initialized.<br />

The fact that structs are value types will affect performance, though depending on how you use your<br />

struct, this can be good or bad. On the positive side, allocating memory for structs is very fast because<br />

this takes place inline or on the stack. The same goes for removing structs when they go out of scope. On<br />

the negative side, whenever you pass a struct as a parameter or assign a struct to another struct (as in A=B,<br />

where A <strong>and</strong> B are structs), the full contents of the struct are copied, whereas for a class only the reference<br />

is copied. This will result in a performance loss that depends on the size of the struct, emphasizing the<br />

fact that structs are really intended for small data structures. Note, however, that when passing a struct<br />

as a parameter to a method, you can avoid this performance loss by passing it as a ref parameter — in<br />

this case, only the address in memory of the struct will be passed in, which is just as fast as passing in a<br />

class. If you do this, though, be aware that it means the called method can in principle change the value of<br />

the struct.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!