1

I'm looking to write C# simple statement using static bool which return true the first time, then always false.

    static bool _firstTime = true;
    static bool FirstTime
    {
            get
            {
                    bool old = _firstTime;
                    _firstTime = false;
                    return old;
            }
    }

This works, but i'm looking for something shorter without temporary variable (here "old").

Thanks.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
BartmanDilaw
  • 398
  • 4
  • 15
  • 3
    Does it need to be thread safe? as this is obviously not – TheGeneral Jul 10 '19 at 22:22
  • 3
    What’s wrong with what you have? It makes the behavior crystal clear. – John Wu Jul 10 '19 at 22:23
  • 2
    `if (!_firstTime) { return false; } else { _firstTime = false; return true; }` – Blorgbeard Jul 10 '19 at 22:25
  • 1
    @TheGeneral : not my point right now... but now understand why :) – BartmanDilaw Jul 10 '19 at 22:29
  • 2
    Generally you ask these sort of questions on other Stack Exchange sites (because your current code works, there is no issue other than improving it). There may be sites dedicated to code review but be sure you read the appropriate FAQ and reformat your question as necessary before posting –  Jul 10 '19 at 22:34
  • 3
    https://dotnetfiddle.net/4vM8mc – mjwills Jul 10 '19 at 22:40
  • @Renat Given the popularity of your answer below, if you adapt it slightly as per my dotnetfiddle link I think it would make sense to undelete it. – mjwills Jul 10 '19 at 22:51

3 Answers3

3

You can return the result of an assignment in C#, which means you could do a comparison, and if firstTime is true, you can return the negative of assigning it to false:

private static bool firstTime = true;
public static bool FirstTime => firstTime ? !(firstTime = false) : firstTime;

But your way is easier to understand.

Note: this is exactly as thread safe as your original code (which you said "works"), meaning it's not thread safe.

Rufus L
  • 36,127
  • 5
  • 30
  • 43
2

If you want something thread-safe and compact, Interlocked.Exchange() fits the bill. It will set your variable and return the old value (exactly what you did in your code) in a thread-safe manner.

The only caveat is that your private field can't be a bool. But whatever happens behind a public property shouldn't matter externally anyway.

static int _isFirstTime = 1;
public static bool IsFirstTime => Interlocked.Exchange(ref _isFirstTime, 0) != 0;
NPras
  • 3,135
  • 15
  • 29
  • 2
    https://stackoverflow.com/a/5341252/34092 and https://stackoverflow.com/questions/4187914/average-latency-of-atomics-cmpxchg-instructions-on-intel-cpus cover it a little. – mjwills Jul 11 '19 at 00:52
  • 'tis a deep rabbit hole indeed. With the best answer being "under ideal conditions, the best implementation puts them at equal", I guess. – NPras Jul 11 '19 at 01:13
0

You may abuse that && is a short circuit like below. But don't use it at work, as your first example is much more easier to read. And it isn't thread safe.

static bool _firstTime = true;

private static bool FirstTime
    => _firstTime && !(_firstTime = false);
Renat
  • 7,718
  • 2
  • 20
  • 34