DEV Community

Discussion on: Read-once variable - R1V, ROV, ... - in C#

Collapse
 
peledzohar profile image
Zohar Peled • Edited

With only a bit of twitches you can get a much more flexible design:

public class ReadValueOnlyXTimesThingy<T>
{
    private T _value;

    public R1V(int maxNumberOfReads, T value)
    {
        if(maxNumberOfReads <= 0) throw new ArgumentOutOfRangeException("maxNumberOfReads must be a positive value");
        ReadsLeft = maxNumberOfReads;
        _value = value;
    }

    public int ReadsLeft {get; private set;}

    public T Value 
    {
        get
        {
            if(ReadsLeft <= 0)
            {
                _value = default(T);
            }
            ReadsLeft--;
            return _value;
        } 
    }
}

And the usage:

var selfDestructingMessage = new ReadValueOnlyXTimesThingy<string>(3, "this message will self destruct after 3 reads.");

// some code here

var theMessage = selfDestructingMessage.Value;

Notes:

  1. This allows as many reads as set in it's constructor.
  2. In case T is a value type, it's default will return a value - 0 for numbers, false for bool and so on. This might not be a desirable outcome once the value have been read the allowed number of times, since it's default value might be indistinguishable from the previous value (think of initializing this class with 1, false - you'll always get false back. One way to handle this is to restrict the T to reference types only, another is to change the property return type to a tuple of bool, T - or perhaps throw an exception - Though that would probably be the last thing I would recommend - as this kind of thing is what Eric Lippert would call a vexing exception, and as usual, he knows what he is writing about.
Collapse
 
bugmagnet profile image
Bruce Axtens

Extra love-button clicking for the use of the word "thingy".

Collapse
 
peledzohar profile image
Zohar Peled
Thread Thread
 
anras573 profile image
Anders Bo Rasmussen

It might be cleaner to return a Maybe, insted of returning null or default(T).

Thread Thread
 
peledzohar profile image
Zohar Peled

If you are already using this nuget, then yes. Otherwise, assuming you're only working with reference types, It introduces more complexity than a simple is object test for reference types.

Anyway, this is a good option to keep in mind.