4

I need a class to store a mutable value. When an instance of this class is shared between different parts of code and one part changes the value inside that object, all the other parts see the new value.

This question isn't how I could write it. Here it is for anyone searching:

public class ValueHolder<T> { public T Value { get; set; } }

My question is, does this class exist anywhere in the standard library? This feels like something that would be included in the many small classes it provides.

Or, is there another way I could achieve my required outcome without littering my code with small classes?

Update/Commentary:
I'm a little bit surprised by the amount of negativity this question raised.
"This leads to a high WTF count!" "You are reinventing!"

Reinventing was something I explicitly set out to avoid in asking this question. If there was something in the standard library already, I could use that instead of writing a new class. (So long as the benefits outweighed the costs.)

The technique, passing an object and allowing it to be modified, is used all the time. Have you ever written a function that takes a List in order for that function to add/remove values? What about an event handler (such as Form.Closing) that allows the event handler to change the ongoing event by setting a value inside the event-args object?

In my case, the object was just a class with a single bool value in it. It gets passed into another piece of code in order to allow that flag to be raised or lowered. You might say that this should be a function's return value or a ref parameter, but I'm using a framework which allows for objects to be passed along to handlers (similar to ParameterizedThreadStart or the Tag properties) so I'm limited in what I can pass around.

"I wonder if the standard library already has a class that does this." I thought to myself. "Let's find out!"

billpg
  • 3,195
  • 3
  • 30
  • 57
  • 2
    Why not just put a reference to `Value` in the class into which you intend to put a reference to `ValueHolder`? – Matthew Watson Jun 05 '15 at 09:26
  • @MatthewWatson Why not indeed.I guess my instructors were quite successful in teaching me that you always need to provide accessors instead of allowing public access to values. – billpg Jun 05 '15 at 09:29
  • Well obviously you would provide a getter and setter to access the value from the class, just like you did in `ValueHolder`. So my question remains: What advantage does adding this extra `ValueHolder` class give you? Why is `myInstance.MyValueHolder.MyValue = "value";` better than `myInstance.MyValue = "value";`? Is it because it is for value types rather than reference types? – Matthew Watson Jun 05 '15 at 09:31
  • Gotcha. There is no single class that you've called myInstance. Separate sections of code passing objects between each other. Think of it like C++ style mutable string objects. You could pass around instance of strings and change their internal value. You can't do that with C# strings. (Or ints, etc) – billpg Jun 05 '15 at 09:39
  • @MatthewWatson There is a big difference: let's say `Value` is a `string`, so immutable. By using `ValueHolder<>`, multiple classes can see if the `string` is "changed" (replaced) – xanatos Jun 05 '15 at 09:39
  • You would be much better off encapsulating the mutable data in a class specifically for that purpose. Personally I'd make accessing mutable data like that a method call to emphasise that it's mutable. I personally don't like properties that change as a side-effect of a call to a seemingly unrelated class. – Matthew Watson Jun 05 '15 at 09:40
  • @xanatos Hence my "Or is it because it is for value types rather than reference types" (in which category I include reference types that behave like value types, i.e. strings and immutable reference types) – Matthew Watson Jun 05 '15 at 09:41
  • Fair points, but my central question remains - Does that class already exist or do I have to write it? (My example "ValueHolder" was more to pre-empt a "Here you are" answer with an implied "Couldn't you have written that yourself?". Followed by a "Yes I could, but that wasn't my question.") – billpg Jun 05 '15 at 09:43
  • 1
    There isn't as far as I know (and I think it would be somewhat of an anti-pattern...). . Usually there are better ways to handle these things in C# (e.g. INotifyPropertyChanged or Reactive Extensions) – Matthew Watson Jun 05 '15 at 09:50
  • 1
    You are re-inventing [`Tuple`](https://msdn.microsoft.com/en-us/library/dd386941%28v=vs.110%29.aspx). It does forever end up behind the [door on the right](http://i.imgur.com/NtPMpXD.png). – Hans Passant Jun 05 '15 at 09:59
  • 1
    Please do check what the door on the right is all about though. ;) Also note that this won't compile: `var test = Tuple.Create("TEST"); test.Item1 = "New";` in case that's what you're thinking of doing... – Matthew Watson Jun 05 '15 at 10:04
  • You can look at [`StrongBox`](https://msdn.microsoft.com/library/bb549038.aspx). Although `Value` here is field not property. – user4003407 Jun 05 '15 at 11:27
  • Perfectly valid question, Tuple is immutable and changing the value passed as reference in an iterator class is not possible. – too Jul 18 '18 at 10:58

3 Answers3

-2

Here is my VolatileRef class.

I use it when I need to pass around a volatile variable by reference.

If you do not care for volatility, just get rid of the volatile keyword and rename the class to just Ref.

public class VolatileRef
{
    private volatile object payload;

    public VolatileRef( object payload )
    {
        this.payload = payload;
    }

    public object Payload { get => payload; set => payload = value; }
}

public class VolatileRef<T> : VolatileRef
{
    public VolatileRef( T payload )
            : base( payload )
    { }

    public new T Payload { get => (T)base.Payload; set => base.Payload = value; }
}
Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
-3

To register and get objects anywhere on my project and at anytime on my app lifecycle, I use Lazy objects :

public static class ServiceContainer
{
    static readonly Dictionary<Type, Lazy<object>> services = new Dictionary<Type, Lazy<object>>();

    public static void Register<T>(Func<T> function)
    {
        services[typeof(T)] = new Lazy<object>(() => function());
    }

    public static T Resolve<T>()
    {
        return (T)Resolve(typeof(T));
    }

    public static object Resolve(Type type)
    {
        Lazy<object> lazy;
        if (services.TryGetValue(type, out lazy))
            return lazy.Value;
        throw new Exception("Not found!");
    }
}

For using :

public class Program 
{
    public void Main()
    {
        ServiceContainer.Register<IFoo>(() => new Foo()); /*register foo*/
    }

    public void UsingFoo()
    {
        var foo = ServiceContainer.Resolve<IFoo>(); /* do something with foo... */
    }
}

You can find more about Lazy objects here :

Andres Talavera
  • 2,100
  • 2
  • 17
  • 29
-4

You can use a Tuple in this way.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794