我可以防止私有变量被同一类的其他对象更改吗?

问题描述 投票:0回答:5

我正在对实时游戏进行多线程处理,并且希望防止从另一个线程设置一个线程上对象的状态变量。这将使防止竞争条件变得更加容易。

但是,我仍然希望能够读取其他对象的状态。我打算使用双缓冲区系统,其中一个状态对象用作前缓冲区并进行状态更改,而另一个状态对象用作后缓冲区并向其他对象提供(前一帧的)状态。我需要能够从后缓冲区读取状态信息以在前缓冲区中进行更改。

问题是,即使变量设置器是私有的,也可以从同一类的另一个对象更改它。

    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";
        }
    }
c# multithreading state access-modifiers
5个回答
2
投票

可能不是最直接的解决方案,但保护属性的一种方法是使用接口。

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
投票

如果您正在编写一个类,则假定您将使该类按照您希望的方式运行。将内容设为私有的目的是防止您的同事(或客户)在处理自己的类/函数/模块时破坏您的类的关注点。
说“我不想做这件事”。有点没有抓住重点。

也就是说,一般来说,不太宽松的语言的好处是,它们可以防止你的同事编写蹩脚或不惯用的代码。其他答案显示了您可以使用的习语,这些习语将使您的同行以后更难编辑打破您漂亮的优雅模式。 Anu Viswan 的 得到我的投票。


0
投票

添加字段 this0=this 并在设置器中检查 this==this0.


0
投票

可以从同一类的另一个对象更改它。

您无法阻止自己的类设置私有设置器。

我的意思是,毕竟你是该课程的作者,你需要担心的只是你的手指。

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;
}

0
投票

这里的每个人都是对的:你无法保护类的属性/字段免受自身侵害。然而,您“可以”会让您自己和其他人更难在这些属性上犯错误。创建一个包含 getter 和 setter 的私有类,并将仅 getter 的属性/字段保留在新创建的私有类之外。如果您不太关心线程安全,则可以将私有类中的所有内容保留为静态。但是,如果您担心线程安全,您仍然可以使用静态类,只要您使用线程安全类型(例如 Lazy)声明变量即可。

© www.soinside.com 2019 - 2024. All rights reserved.