Click here to Skip to main content
15,885,278 members
Articles / Programming Languages / Visual Basic
Article

Preserve properties of an object and have them restored automatically

Rate me:
Please Sign up or sign in to vote.
2.91/5 (11 votes)
7 Dec 20037 min read 62.8K   50   19   10
Simple technique to preserve the state of an object and have the state restored when a function exits

Introduction

One of the challenges of working with objects is returning property values, which you have changed, to their original state. This can mean writing the same lines of code again and again in any functions which change properties, that must be returned to the same value they possessed before your code "dirtied" the object.

This article presents what I feel is a reasonable solution that can be applied to C++, C#, VB or VB.NET, and can be understood by developers of all experience levels. For the beginner it presents an introduction to objects and issues related to object lifetime. For the advanced developers it shows us how we can take advantage of certain behaviours to save significant amounts of coding effort, and retain a uniform approach to protecting the values of objects which are shared amongst various processing sub-routines.

The Approach

The approach is very simple, it involves creating a simple class whose constructor retains a reference to an object and then moves on to preserve known property values, that the developer wishes to protect. I refer to such objects as the Protectors.

A Protector is any class which protects the values of another object such that when the Protector is destroyed, the object which is being protected has its property values reset to their initial values, which were in use at the time the Protector was created.

A Protected Object is an object whose property values can change and subsequently be automatically restored, in other words it is guarded by a Protector.

When a Protector is instantiated the object requiring protection is passed as a reference to the Protector, together with values which are to be assigned to properties of the

VB.NET
Protected 
Object
.

This approach works in object orientated language as instatiation and destruction of objects automatically causes known sub-routines to be executed. These known sub-routines are often referred to as Constructors and Destructors. In Visual Basic, they are known as SUB NEW and

VB.NET
SUB 
FINALIZE
.

Words of Caution

The behvior of OO languages when creating and destroying objects differs widely. For example, in C++ when you destroy an object its destructor is called immediately. This is not the case in VB.NET (see the documentation on FINALIZE for an explanation). Therefore the downloadable example is a moredetailed and accurate demonstration of how to implement Protector objects, as they are described below.

This means that two lines of code are required to utilise Protector objects, the first being to create a Protector and the second to Dispose it.

Overview of Example

The example offered is described by the use of VB.NET code, but translation to C++ or C# is a trivial matter.

The SUB NEW for the

VB.NET
Protector 
accepts two parameters, the first the object reference to the Protected Object and the second parameter is a value which is assigned to a property of the Protected Object.

Therefore, in the example code below, the only two methods available on the Protector are the

VB.NET
Sub New 
and Sub Finalize sub-routines. The Sub New is effectively called by the developer creating a new Protector, whilst VB.NET will automatically call the Sub Finalize routine when the Protector object is destroyed.

The Lifetime of the Protector

The lifetime of the protector in the example is the scope of a single sub-routine which utilises the

VB.NET
Protector 
object. That is to say that, when the sub-routine begins the Protector is created, and when the sub-routine ends the protector is automatically destroyed, a process often referred to as "going out of scope".

The approach can be used within any scope though, eg: a Protector can exist at module level, the developer can also create and destroy protectors at will using the syntax NEW and MyProtector = Nothing, effectively creating a new Protector then destroying it.

Example Code

The following example code sections provide a basic outline of Protectors. In reality, writing a protector is more involved, however, the pay offs can still be significant.

Please download and study the sample code for an accurate implementation of the Protector concept in VB.NET.

The purpose of this example is to protect the

VB.NET
SmoothingMode 
property of a GraphicsObject, such that the developer can change SmoothingMode to any value during the course of a sub routine and have SmoothingMode returned to its original value when the sub-routine completes.

VB.NET
Public Class GraphicsProtector

    Dim mGraphics as GraphicsObject
    Dim mSmoothingMode as SmoothingMode
 

    '
    ' Constructor stores the object reference and relevant properties
    '
    Sub New(ByRef prObject as Graphics, ByVal pvNewMode as SmoothingMode)    
        mGraphics = prObject
        mSmoothingMode = mGraphics.SmoothingMode
        mGraphics.SmoothingMode = pvNewMode
    End Sub  
 
    '
    ' Destructor restores values back to properties
    '
    Protected OverRides Sub Finalize()
        mGraphics.SmoothingMode = mSmoothingMode
    End Sub

End Class

The preceeding code describes a simple class which protects the SmoothingMode property of the specified

VB.NET
Graphics 
object. The following example now illustrates how the Protector named
VB.NET
GraphicsProtector 
operates to ensure that the Graphics object SmoothingMode property is reset to its initial value when the sub-routine completes.

VB.NET
Sub DrawSmoothRectangle (ByRef prGraphics as Graphics)
    ' Create the protector, store the object reference 
    ' and change the property
    Dim lProtector As GraphicsProtector = New GraphicsProtector( _
          prGraphics, SmoothingMode.HighQuality)

    ' Do some drawing
    prGraphics.DrawRectangle(....)
    prGraphics.FillEllipse(...)
    ' Now the lProtector object will go out of scope
    ' and automatically restore the objects property values
End Sub

The preceeding code is an outline which illustrates the kinds of methods which may benefit from having graphical smoothing effects applied. For instance, when prGraphics is passed into the sub-routine DrawSmoothRectangle it could have a value of SmoothingMode.HighSpeed, which may not give the desired graphical quality, therefore the sub-routine changes this to SmoothingMode.HighQuality, but the developer would then have to ensure this property is returned to its original value of SmoothingMode.HighSpeed, else risk slowing down all other drawing processes which occur after this sub-routine completes, something which is very easy to forget and causes all maner of problems.

Using this approach, the developer no longer needs to remember to restore the value. Only one line of code is required to switch the property to its new value and have the original preserved.

The Chain of Events

  • DrawSmoothRectangle is passed a Graphics object into which the developer can draw miscellaneous shapes.
  • The developer switches the SmoothingMode to the desired quality, and has the original value preserved by the GraphicsProtector object
  • The developer proceeds to draw.
  • The GraphicsProtector object then goes "out of scope", i.e. it is automatically destroyed when the sub-routine ends.
  • At the time that the GraphicsProtector goes out of scope it restores the value of prGraphics.Smoothing mode to its original value.

For clarfification; rather than letting the system the destroy the object automatically at the end of the DrawSmoothRectangle routine, the developer could have written

VB.NET
' Setting an object variable to nothing destroys the object
' being referred to (as long as no other variables refer to the object)
lProtector = Nothing

This too would have destroyed the GraphicsProtector object (lProtector), but the whole point of this approach is to write as little code as possible to achieve the maximum amount of housekeeping.

Advancing the Concept

From this simple start point the Sub New, or constructor, can be modified to accept values for numerous properties so that in a single line, multiple properties are preserved and assigned, which affords the developer great relief from repetitive coding.

Protectors can be instantiated and destroyed at will, not just at the top of sub-routines. Any time the need arises to protect some values whether its on the first or tenth line of a routine a Protector can be instantiated and manually or automatically destroyed.

Other examples of protectors are remembering the size and position of windows. The names, styles and sizes of fonts in use on a form. The style of the mouse cursor, all of which are things that the developer could change, and if not aware of the impact of such changes on successive functions erroneous conditions can arise within an application.

Conclusion

Utilising the automatic behaviour of object orientated systems provides great leverage. With a little thought elaborate schemes can be concocted from very simple techniques, the result being that small amounts of code can achieve immensely useful results, be those results measured in time saved in developement, or in later maintenance and support of code written using such techniques.

PLEASE NOTE: You must utilise Protectors as completely depicted in the example source code, otherwise you will experience very strange errors, which occur due to the .NET system disposing your objects at its discretion, as opposed to when you ACTUALLY want them disposed. (Thanks to Ian Darling for his reminder on this very important issue.)

I thank you for reading this article and for taking time to score my efforts, such that I can measure my contribution to this forum, from which I have gained immensly useful examples, and contact with people whose oppinion I hold in very high esteem.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Australia Australia
English guy now living in Australia. Developed in VB/C++ and assembler for many years. Just begun working with .NET. Keen to develop many resuable components. Have great system at home.

Comments and Discussions

 
GeneralDesign Patterns Pin
mogwai8-Dec-03 23:19
mogwai8-Dec-03 23:19 
GeneralRe: Design Patterns Pin
15-Dec-03 9:32
suss15-Dec-03 9:32 
GeneralRe: Design Patterns Pin
cnurse15-Dec-03 13:29
cnurse15-Dec-03 13:29 
GeneralRe: Design Patterns Pin
cnurse15-Dec-03 13:32
cnurse15-Dec-03 13:32 
GeneralNice idea Pin
Ian Darling8-Dec-03 3:34
Ian Darling8-Dec-03 3:34 
GeneralRe: Nice idea Pin
cnurse8-Dec-03 14:50
cnurse8-Dec-03 14:50 
GeneralRe: Nice idea Pin
Ian Darling8-Dec-03 22:25
Ian Darling8-Dec-03 22:25 
GeneralRe: Nice idea Pin
cnurse8-Dec-03 22:45
cnurse8-Dec-03 22:45 
GeneralRe: Nice idea Pin
cnurse8-Dec-03 22:48
cnurse8-Dec-03 22:48 
GeneralRe: Nice idea Pin
Ian Darling8-Dec-03 22:56
Ian Darling8-Dec-03 22:56 
cnurse wrote:
Any ideas would be appreciated

Unfortunately I have none. I have added things to the toolbox (ASP.NET controls), and they don't cause me any problems like that, but I haven't done any toolbox stuff otherwise.

--
Ian Darling
"The moral of the story is that with a contrived example, you can prove anything." - Joel Spolsky

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.