Могу ли я предотвратить изменение закрытой переменной другими объектами того же класса? - PullRequest
0 голосов
/ 04 января 2019

Я использую многопоточность игры в реальном времени, и хотел бы, чтобы переменные состояния объектов в одном потоке не устанавливались из другого потока.Это значительно упростит предотвращение гонки.

Однако я бы хотел прочитать состояние других объектов.Я намерен использовать систему с двойным буфером, где один объект состояния используется в качестве предбуфера и вносит изменения в состояние, в то время как другой используется в качестве резервного буфера и предоставляет состояние (предыдущего кадра) другим объектам.Мне нужно иметь возможность читать информацию о состоянии из буфера, чтобы вносить изменения в буфере.

Проблема в том, что даже если установщик переменных является закрытым, его можно изменить из другого объекта того же класса.

    public class State
    {
        //Some example state information
        public string StateVar1 { get; private set; }

        //This method will be farmed out to multiple other threads
        public void Update(State aDifferentStateObject)
        {
            StateVar1 = "I want to be able to do this";
            string infoFromAnotherObject = aDifferentStateObject.StateVar1; //I also want to be able to do this
            aDifferentStateObject.StateVar1 = "I don't want to be able to do this, but I can";
        }
    }

Ответы [ 4 ]

0 голосов
/ 04 января 2019

добавьте поле this0 = this и в установщике убедитесь, что this == this0.

0 голосов
/ 04 января 2019

Возможно, это не самое прямое решение, но один из способов защиты свойств - это использование интерфейса.

public interface IState
{
    string StateVar1 { get; }
}

public class State:IState
{
    //Some example state information
    public string StateVar1 { get; private set; }

    //This method will be farmed out to multiple other threads
    public void Update(IState aDifferentStateObject)
    {
        StateVar1 = "I want to be able to do this";  // Allowed
        string infoFromAnotherObject = aDifferentStateObject.StateVar1; 
        aDifferentStateObject.StateVar1 = "I don't want to be able to do this, but I can"; // NOT allowed
    }
}
0 голосов
/ 04 января 2019

Если вы пишете класс, предполагается, что вы заставите класс работать так, как вы хотите, чтобы он работал.Цель сделать вещи частными - не дать вашим коллегам (или клиентам) нарушить заботы вашего класса, пока они работают над своими собственными классами / функциями / модулями.
Сказать «Я не хочу этого делатьвещь."в некоторой степени упускает из виду.

Тем не менее, в менее разрешающих языках в целом хорошо то, что они мешают вашим коллегам писать дерьмовый или неидиоматический код.Другие ответы показывают идиомы, которые вы могли бы использовать, чтобы вашим коллегам было труднее потом редактировать, нарушать ваш красивый элегантный шаблон. Ану Вишван получает мой голос.

0 голосов
/ 04 января 2019

его можно заменить другим объектом того же класса.

Вы не можете запретить своему классу устанавливать частные сеттеры.

Я имею в виду, в конце концов, вы автор этого класса, вам нужно беспокоиться только о своих пальцах.

public class SomeOtherNonRelatedClass
{
     public void Update(State aDifferentStateObject)
     {
        // the world is as it should be
        aDifferentStateObject.StateVar1 = "bang!!!" // compiler error
     }
}

Если вы хотите помешать себе изменить свою собственнуючлен, затем используйте метод расширения

public class Extensions
{
     public void Update(this State aDifferentStateObject)
     {
        // the world is as it should be
        aDifferentStateObject.StateVar1 = "bang!!!" // compiler error
     }
}

или сделайте его действительно доступным только для чтения (хотя это, вероятно, бесполезно)

public string StateVar1 { get; }

или вспомогательное поле, так что вы можете установить его внутренне

private string backingField;

public string StateVar1
{
    get => backingField;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...