'Doing a fuse with a boolean

I have a lot of pieces of code which has to be run one time during initialization.

I have to use a boolean flag this way because it is in an event

bool _fuse;

void PerformLayout()
{
    Size size;

    if (!_fuse)
    {
        size = _InitialContainerSize;
        _fuse = true;
    }
    else
        size = parent.Size;

    // ...
}

Because it happens often, I did something to make this boolean variable to look like a fuse :

So I did this:

bool _fuse;

void PerformLayout()
{
    Size size;

    if (!Burnt(ref _fuse))
        size = _InitialContainerSize;
    else
        size = parent.Size;

    // ...
}

If it is initialized to false, the result of the query returns false once, make the switch to true, and successive calls return true.

public static bool Burnt(ref bool value)
{
    if (!value)
    {
        value = true;
        return false;
    }
    else
        return true;
}

Of course, it works, but I am only moderately satisfied and I am sure there is more elegant solutions. What would be yours ?



Solution 1:[1]

I think the general thrust in avoiding repetition here is right (even if the repetition is very small … but still). Just encapsulate it and name it properly:

struct InitializerGuard {
    private bool hasRun;

    public bool HasRun() {
        if (hasRun)
            return true;
        hasRun = true;
        return false;
    }
}

Usage:

InitializerGuard sizeInitializer;

void PerformLayout()
{
    Size size;

    if (!sizeInitializer.HasRun())
        size = _InitialContainerSize;
    else
        size = parent.Size;

    // ...
}

But if you find yourself using this pattern very often this might indicate that a refactoring is in order. Maybe just assign default values to some variables? Why aren’t they initialised, anyway?

Solution 2:[2]

There are many ways of achieving this. You can create a complex state machine performing your logic (fastest) but for many cases, that will be overkill. Alternatively, you can keep track of an boolean which holds the state of your instance just like you have now. You can also decide to combine both solutions into a simple state machine with methods like (moderatly fast):

public class TestClass
{
    private Action performLayoutAction;

    public TestClass()
    {
        // initial state
        performLayoutAction = InitializePeformLayout;
    }

    public void PerformLayout()
    {
        performLayoutAction();
    }

    private void InitializePeformLayout()
    {
        // whatever 

        performLayoutAction = ContiniousPerformLayout;
    }

    private void ContiniousPerformLayout()
    {
        // whatever 
    }
} 

Solution 3:[3]

You can use nullable types and the null coalescing operator to declare a Size property:

Size? _containerSize;

Size ContainerSize {
  get {
    return (_containerSize ?? (_containerSize = _InitialContainerSize)).Value;
  }
}

You can then use it like this:

void PerformLayout() { 
  var size = ContainerSize;
  // ...
}

If the type you want to lazy initialize is a reference type it becomes even simpler.

Another option is to use the Lazy<T> type. This can used in multi-threading scenarios where the above code can break:

Lazy<Size> _containerSize = new Lazy<Size>(() => _InitialContainerSize);

void PerformLayout() { 
  var size = _containerSize.Value;
  // ...
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Konrad Rudolph
Solution 2 Polity
Solution 3