Struct Types


In Chapter 8, I noted that structs and classes are very similar, but that structs are value types and classes are reference types. So, what does this actually mean to you? Well, the simplest way of looking at this is to look at an example like that in the following Try It Out.

Try It Out – Classes versus Structs

image from book
  1. Create a new console application project called Ch09Ex03 in the directory C:\BegVCSharp\ Chapter9.

  2. Modify the code as follows:

    namespace Ch09Ex03 { class MyClass { public int val; } struct myStruct { public int val; }        class Program    {       static void Main(string[] args)       { MyClass objectA = new MyClass(); MyClass objectB = objectA; objectA.val = 10; objectB.val = 20; myStruct structA = new myStruct(); myStruct structB = structA; structA.val = 30; structB.val = 40; Console.WriteLine("objectA.val = {0}", objectA.val); Console.WriteLine("objectB.val = {0}", objectB.val); Console.WriteLine("structA.val = {0}", structA.val); Console.WriteLine("structB.val = {0}", structB.val); Console.ReadKey();       }    } } 

  3. Run the application. The output is shown in Figure 9-17.

    image from book
    Figure 9-17

How It Works

This application contains two type definitions, one for a struct called myStruct, which has a single public int field called val, and one for a class called MyClass that contains an identical field (you look at class members such as fields in the next chapter, for now it's enough just to point out that the syntax is the same here). Next, you perform the same operations on instances of both of these types:

  • Declare a variable of the type.

  • Create a new instance of the type in this variable.

  • Declare a second variable of the type.

  • Assign the first variable to the second variable.

  • Assign a value to the val field in the instance in the first variable.

  • Assign a value to the val field in the instance in the second variable.

  • Display the values of the val fields for both variables.

Although you are performing the same operations on variables of both types, the outcome is different. When you display the values of the val field, you find that both object types have the same value, while the struct types have different values.

So, what has happened?

Objects are reference types. When you assign an object to a variable you are actually assigning that variable with a pointer to the object it refers to. A pointer, in real code terms, is an address in memory. In this case the address is the point in memory where the object is found. When you assign the first object reference to the second variable of type MyClass with the following line, you are actually copying this address.

MyClass objectB = objectA;

This means that both variables contain pointers to the same object.

Structs are value types. Instead of the variable holding a pointer to the struct, the variable contains the struct itself. When you assign the first struct to the second variable of type myStruct with the following line, you are actually copying all the information from one struct to the other.

myStruct structB = structA; 

You have seen behavior like this earlier in this book for simple variable types such as int. The end result is that the two struct type variables contain different structs.

This whole technique of using pointers is hidden from us in managed C# code, making your code much simpler. It is possible to get access to lower-level operations such as pointer manipulation in C# using unsafe code, but that is an advanced topic that I won't cover here.

image from book

Shallow versus Deep Copying

Copying objects from one variable to another by value instead of by reference (that is, copying them in the same way as structs) can be quite complex. Because a single object may contain references to many other objects, such as field members and so on, there may be an awful lot of processing involved. Simply copying each member from one object to another might not work, because some of these members might be reference types in their own right.

the .NET Framework takes this into account. Simple object copying by members is achievable through the method MemberwiseClone(), inherited from System.Object. This is a protected method, but it would be easy to define a public method on an object that called this method. The copying supplied by this method is known as shallow copying, in that it doesn't take reference type members into account. This means that reference members in the new object will refer to the same objects as the equivalent members in the source object, which isn't ideal in many cases. If you want to create new instances of the members in question, copying the values across rather than the references, then you need to perform a deep copy.

There is an interface you can implement that allows you to do this in a standard way: ICloneable. If you use this interface, you must implement the single method it contains, Clone(). This method returns a value of type System.Object. You can use whatever processing you wish to obtain this object, by implementing the method body however you choose. This means that you can implement a deep copy if you wish to (although the exact behavior isn't mandatory, so you could perform a shallow copy if you wanted to).

You take a closer look at this in Chapter 11.




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

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