Чтобы работать так, как описано выше, вам нужно иметь его неизменным (без установщика) - возможно, с некоторыми неявными операторами преобразования для удобства. В противном случае люди могут изменить значение, не изменяя (изменчивую) ссылку.
public class MyThreadedClass
{
volatile Box<double> volDouble = 123.45;
}
public class Box<T> where T : struct
{
private readonly T value;
public Box(T value) { this.value = value; }
public T Value {get {return value;}}
// explicit as nulls are a problem...
public static explicit operator T(Box<T> box) {
return box.value; }
public static implicit operator T?(Box<T> box) {
return box == null ? new T?() : new T?(box.value); }
public static implicit operator Box<T>(T value) {
return new Box<T>(value); }
public static implicit operator Box<T>(T? value) {
return value.HasValue ? new Box<T>(value.Value) : null; }
}
Кроме того, блокировка будет лучшим вариантом.