OneShotFlag#

If you've ever written some test code before (you do write unit tests, don't you?), you probably ran into the common code construct that you initialize a "success" flag to a certain value so you can toggle its state later on. I just wrote a little utility class to guard you from making mistakes here: a boolean-like flag that can only change its state (value) once.

Normally, you would initialize a boolean flag to the expected outcome and then only change that flag if one of the tests failed. You can't set the flag directly everytime because that can reset the value when it should not be reset (e.g. if one test succeeds then the failure of the previous tests would be "forgotten").

Bad code (the result of the first test won't ever matter):

bool success = true; // We expect this to work.
success = !HasFirstTestSucceeded();
success = !HasSecondTestSucceeded();
// ...
if( success ) Party();

Better code (semantically correct but cumbersome):

bool success = true; // We expect this to work.
if( !HasFirstTestSucceeded() ) success = false; // Only change the value if necessary.
if( !HasSecondTestSucceeded() ) success = false;
// ...
if( success ) Party();

So you have to write code that only changes the flag if it differs from its initial state. This is just where the OneShotFlag class helps: it only allows the flag to be changed only once. Furthermore, it can implicitly be converted to a boolean so checking its state is just as easy.

But it becomes more natural like this:

OneShotFlag success = new OneShotFlag( true ); // We expect this to work.
success.State = HasFirstTestSucceeded(); // Change the value directly.
success.State = HasSecondTestSucceeded();
// ...
if( success ) Party(); // Note the implicit conversion to a boolean here!

Here's the code for the class:

public class OneShotFlag
{
 /// <summary>
 /// The current state of the flag.
 /// </summary>
 private bool m_State;
 /// <summary>
 /// Indicates if the flag has already changed its value once.
 /// </summary>
 private bool m_ShotFired;
 /// <summary>
 /// Creates a new <see cref="OneShotFlag"/>.
 /// </summary>
 /// <param name="initialState">The initial <see cref="State"/> of the flag.</param>
 public OneShotFlag( bool initialState )
 {
  m_ShotFired = false;
  m_State = initialState;
 }
 /// <summary>
 /// Gets or sets the current state of the flag. The state will effectively be changed only once.
 /// </summary>
 public bool State
 {
  get
  {
   return m_State;
  }
  set
  {
   if( m_State != value && !m_ShotFired )
   {
    lock( this )
    {
     m_State = value;
     m_ShotFired = true;
    }
   }
  }
 }
 /// <summary>
 /// Requests to change the state. The state will effectively be changed only once.
 /// </summary>
 public void ToggleState()
 {
  State = !State;
 }
 /// <summary>
 /// Implicitly converts the given OneShotFlag to a boolean value.
 /// </summary>
 /// <param name="flag">The OneShotFlag to convert.</param>
 /// <returns>The current <see cref="State"/> of the OneShotFlag.</returns>
 public static implicit operator bool( OneShotFlag flag )
 {
  return flag.State;
 }
}

Comments are closed.
All content © 2008, Jelle Druyts
On this page

Recent Photos
www.flickr.com
This is a Flickr badge showing public photos from Jelle Druyts. Make your own badge here.
Advertising
Top Picks
Statistics
Total Posts: 344
This Year: 7
This Month: 0
This Week: 0
Comments: 522
Archives
Sitemap
Disclaimer
This is my personal website, not my boss', not my mother's, and certainly not the pope's. My personal opinions may be irrelevant, inaccurate, boring or even plain wrong, I'm sorry if that makes you feel uncomfortable. But then again, you don't have to read them, I just hope you'll find something interesting here now and then. I'll certainly do my best. But if you don't like it, go read the pope's blog. I'm sure it's fascinating.

Powered by:
newtelligence dasBlog 2.0.7226.0

Sign In