Как упаковать и распаковать структуру с типом безопасности - PullRequest
0 голосов
/ 04 мая 2020

В платформе. NET есть struct , которую я хотел бы использовать в качестве состояния для своего класса. Важно, чтобы структура была встроенной, поэтому я не могу ее изменить. Допустим, эта встроенная структура имеет вид ImmutableStruct ниже.

struct ImmutableStruct
{
    public string Value { get; }

    public ImmutableStruct(string value) { Value = value; }
}

Мой класс должен быть потокобезопасным, поэтому состояние должно быть объявлено volatile. Конечно, есть и другие способы обеспечения безопасности потоков, но давайте скажем, что поле volatile было выбрано как лучший вариант для конкретного случая c. Поэтому я кодирую свой класс следующим образом:

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 */
}

К сожалению, компилятор не допускает поле структуры volatile. Поэтому я решил использовать упаковку и распаковку :

class MyClass
{
    private volatile object _state = new ImmutableStruct("SomeString");

    public ImmutableStruct State => (ImmutableStruct)_state;

    /* Method that mutates the _state reference is omitted */
}

Это работает, но приведение объектов вызывает у меня беспокойство, потому что программа подвержена возможным ошибкам во время выполнения. Я хотел бы получить безопасное от типов решение с компилятором, обеспечивающим корректность программы во время компиляции. Поэтому мой вопрос таков: есть ли способ пометить и распаковать структуру с типом безопасности?

Кстати, есть связанный вопрос о маркировке структур как volatile: Volatile для структур и коллекций структур . Мой вопрос заключается в том, что он сосредоточен именно на безопасности типов при выполнении операции упаковки / распаковки.

1 Ответ

1 голос
/ 04 мая 2020

Как насчет создания обертки generi c, например:

public  class ReadonlyStructWrapper<T> where T: struct 
    {
        public T Value { get; }
        public ReadonlyStructWrapper(T value)
        {
            Value = value;
        }
    }
...