There is a struct in the .NET platform that I would like to use as state for my class. It is important that the struct is built-in, so I can't change it. Lets say that this built-in struct is the ImmutableStruct
below.
struct ImmutableStruct
{
public string Value { get; }
public ImmutableStruct(string value) { Value = value; }
}
My class is required to be thread-safe, so the state must be declared volatile
. Of course there are other ways to achieve thread-safety, but lets say that a volatile
field has been chosen as the best option for the specific case. So I code my class like this:
class MyClass
{
private volatile ImmutableStruct _state = new ImmutableStruct("SomeString");
// Error CS0677
// 'MyClass._state': a volatile field cannot be of the type 'ImmutableStruct'
public ImmutableStruct State => _state;
/* Method that mutates the _state is omitted */
}
Unfortunately the compiler does not allow a volatile
struct field. So I decide to use boxing and unboxing:
class MyClass
{
private volatile object _state = new ImmutableStruct("SomeString");
public ImmutableStruct State => (ImmutableStruct)_state;
/* Method that mutates the _state reference is omitted */
}
This works, but casting from objects causes me anxiety, because the program becomes exposed to possible run-time errors. I would like a type-safe solution, with the compiler ensuring the correctness of the program at compile-time. So my question is: Is there any way to box and unbox a struct with type safety?
Btw there is a related question about marking structs as volatile
: Volatile for structs and collections of structs. My question defers in that it focuses specifically to the type-safety of the boxing/unboxing operation.
How about creating generic wrapper like this:
public class ReadonlyStructWrapper<T> where T: struct
{
public T Value { get; }
public ReadonlyStructWrapper(T value)
{
Value = value;
}
}