Fuse execution with boolean

I have many pieces of code that need to be executed once during initialization.

I need to use a boolean flag this way because it is in the event

bool _fuse;

void PerformLayout()
{
    Size size;

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

    // ...
}

Since this happens often, I did something to make this boolean 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 query returns false once, set 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, this works, but I'm only moderately satisfied, and I'm sure there are more elegant solutions. What would be yours?

+5
source share
3 answers

, ( ... ). :

struct InitializerGuard {
    private bool hasRun;

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

:

InitializerGuard sizeInitializer;

void PerformLayout()
{
    Size size;

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

    // ...
}

, , . , ? ?

+1

Size:

Size? _containerSize;

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

:

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

, , , .

- Lazy<T>. , :

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

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

There are many ways to achieve this. You can create a complex state machine that executes your logic (faster), but for many cases this will be redundant. In addition, you can track a boolean that contains the state of your instance just as it does now. You can also decide to combine both solutions into a simple state machine with methods such as (moderately 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 
    }
} 
+1
source

All Articles