Best Practices for Designing Structure Types                                        
•        Structures are value types allocated on the stack.
•        In contrast, classes are heap allocated and managed by the CLR garbage collector.
•        For this reason, structures are more lightweight than classes.
•        Because structures are value types, your custom structures should always:
•        Override System.Object.Equals() and System.Object.GetHashCode() to perform value based
comparison semantics.
•        Also override System.Object.ToString() to return a sting representing the value type’s state.
// C#
struct MyPoint
{
public int X, Y;
public MyPoint(int xPos, int yPos)
{ X = xPos; Y = yPos; }

public override string ToString()
{ return string.Format("[{0}, {1}", X, Y); }

public override int GetHashCode()
{ return ToString().GetHashCode(); }

public override bool Equals(object obj)
{
   if (obj is MyPoint)
   {
       MyPoint temp = (MyPoint)obj;
       if(temp.ToString() == this.ToString())
           return true;
       else
           return false;
   }
   return false;
}
}


' VB 2005
Structure MyPoint
Public X As Integer, Y As Integer

Sub New(ByVal xPos As Integer, ByVal yPos As Integer)
   X = xPos : Y = yPos
End Sub

Public Overrides Function ToString() As String
   Return String.Format("[{0}, {1}", X, Y)
End Function

Public Overrides Function GetHashCode() As Integer
   Return ToString().GetHashCode()
End Function

Public Overrides Function Equals(ByVal obj As Object) As Boolean
   If TypeOf obj Is MyPoint Then
       Dim temp As MyPoint = DirectCast(obj, MyPoint)
       If temp.ToString() = Me.ToString() Then
           Return True
       Else
           Return False
       End If
   End If
   Return False
End Function
End Structure
•        As well, consider overloading the equality operators so your types work symmetrically with the CLR
value types (e.g., System.Int32, System.Int16, etc).
•        This makes it simple to use your types within conditional logic.

•        Be aware of the impact of implementing interfaces on structures!
•        When calling code accesses interface members implemented on a structure, you will incur boxing and
unboxing penalties!
•        Recall this feature allows us to pretend everything is an object, however the downside is the stack 
heap memory transfer.
•        For example, assume we have implemented ICloneable on the MyPoint type.
// C#
struct MyPoint : ICloneable
{
public object Clone()
{
return new MyPoint(this.X, this.Y);
}
...
}

' VB 2005
Structure MyPoint
Implements ICloneable

Public Function Clone() As Object Implements System.ICloneable.Clone
   Return New MyPoint(Me.X, Me.Y)
End Function
End Structure

•        When we now access the interface members via the interface, a secret box / unbox occurs:
•        Even worse, if the interface members operate on state data of the structure, you are modifying the
boxed copy, not the local stack allocated copy!
•        Thus, you may find fields set to their default value when you thought you changed the value!
•        Consider the following code.
// C#
static void Main(string[] args)
{
MyPoint p = new MyPoint(10, 10);
ICloneable i = (ICloneable)p;                  // Box!
MyPoint ptCopy = (MyPoint)i.Clone();        // Unbox!
}

' VB 2005
Sub Main()
Dim p As New MyPoint(10, 10)
Dim i As ICloneable = DirectCast(p, ICloneable)  ' Box!
Dim ptCopy = DirectCast(i.Clone(), MyPoint)      ' Unbox!
End Sub

•        Consider the resulting CIL code seen through the eyes of ildasm.exe.
•        Note the box and unbox opcodes.

•        However, if you call the interface members directly from the object level, you avoid the boxing /
unboxing penalties.
•        This cannot be achieved when making use of explicit interface implementation!
•        Given this, avoid implementing interface members on structures using explicit interface implementation.
•        When implementing structures which must perform internal clean up of unmanaged resources,
implement IDisposable.
•        Recall that structures are not allocated on the heap, and therefore cannot support a finalizer method.
Designing Structure Types
Table of Contents
Copyright (c) 2008.  Intertech, Inc. All Rights Reserved.  This information is to be used exclusively as an
online learning aid.  Any attempts to copy, reproduce, or use for training is strictly prohibited.
Courseware
Training Resources
Tutorials