Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以防止私有变量被同一类的其他对象更改吗?_C#_Multithreading_State_Access Modifiers - Fatal编程技术网

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

C# 我可以防止私有变量被同一类的其他对象更改吗?,c#,multithreading,state,access-modifiers,C#,Multithreading,State,Access Modifiers,我正在对一个实时游戏进行多线程处理,希望防止一个线程上的对象的状态变量从另一个线程设置。这将使防止比赛条件变得容易得多 但是,我仍然希望能够读取其他对象的状态。我打算使用双缓冲系统,其中一个状态对象用作前缓冲区并进行状态更改,而另一个用作后缓冲区并向其他对象提供(前一帧的)状态。我需要能够从backbuffer读取状态信息,以便在forebuffer中进行更改 问题是,即使变量设置器是私有的,也可以从同一类的另一个对象更改它 public class State {

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

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

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

    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";
        }
    }
可以从同一类的另一个对象更改它

    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";
        }
    }
您不能阻止自己的类设置私有setter

我的意思是,毕竟,你是这门课的作者,你只需要担心你的手指

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
     }
}
或者使其真正只读(尽管可能没有用处)

或支持字段,以便您可以在内部进行设置

private string backingField;

public string StateVar1
{
    get => backingField;
}
可以从同一类的另一个对象更改它

    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";
        }
    }
您不能阻止自己的类设置私有setter

我的意思是,毕竟,你是这门课的作者,你只需要担心你的手指

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
     }
}
或者使其真正只读(尽管可能没有用处)

或支持字段,以便您可以在内部进行设置

private string backingField;

public string StateVar1
{
    get => backingField;
}

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

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

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

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

如果您正在编写一个类,则假定您将使该类按照您希望的方式工作。将内容私有化的目的是防止您的同事(或客户)在处理自己的类/函数/模块时破坏类的顾虑。
说“我不想做这件事”有点失了重点


这就是说,一般来说,不那么宽容的语言的好处在于,它们可以防止您的同事编写蹩脚或非惯用代码。其他答案显示了你可以使用的习惯用法,这会使你的同龄人以后更难编辑打破你优雅的模式。这是我的投票。

如果你在写一个类,那么假设你会让这个类按照你想要的方式工作。将内容私有化的目的是防止您的同事(或客户)在处理自己的类/函数/模块时破坏类的顾虑。
说“我不想做这件事”有点失了重点


这就是说,一般来说,不那么宽容的语言的好处在于,它们可以防止您的同事编写蹩脚或非惯用代码。其他答案显示了你可以使用的习惯用法,这会使你的同龄人以后更难编辑打破你优雅的模式。获取我的投票。

添加字段this0=this,在setter中检查this==this0。

添加字段this0=this,在setter中检查this==this0。

OP说的是“来自同一类的另一个对象”,而不是“来自另一个类”。您自己已经引用了问题的这一部分,但您似乎误读了。@IgbyLargeman,然后澄清了规则和可能的解决方案,但是您的评论很受欢迎,并采纳了OP的说法:“来自同一类的另一个对象”,而不是“来自另一类”。您自己已经引用了问题的这一部分,但您似乎误读了它。@IgbyLargeman然后澄清了规则和可能的解决方案,但是您的评论很受欢迎并被采纳,但是您仍然可以通过简单地引用类实例来修改StateVar1属性
(adInterfertstateObject作为状态)。StateVar1=“
@IgbyLargeman是的,只要它作为类实例访问,您就可以访问它。这就是为什么他说“不是最直接的解决办法”。这仅在使用接口时有效。感谢您将其用于讨论,但是您仍然可以通过简单地引用类实例来修改StateVar1属性
(adInterfertstateObject作为状态)。StateVar1=“
@IgbyLargeman是的,只要它作为类实例访问,您就可以访问它。这就是为什么他说“不是最直接的解决办法”。这仅在使用接口时有效。如果你创建了一个二传手,你需要一个支持字段。该类的所有实例都可以修改所有其他实例的所有字段。如果创建setter,则需要一个支持字段。该类的所有实例都可以修改所有其他实例的所有字段。您尝试执行的操作毫无意义。作为这个类的作者,你完全可以控制它的功能。如果您不希望类的实例修改其他实例的属性,请不要这样做。您是对的,我可以控制在这个类中编写的内容。然而,我并不是绝对正确的,我不能100%肯定没有人会编辑这个类,而且种族条件是出了名的难以调试。这是一种防范未来错误的机制。你所做的一切毫无意义。作为这个类的作者,你完全可以控制它的功能。如果您不希望类的实例修改其他实例的属性,请不要这样做。您是对的,我可以控制在这个类中编写的内容。然而,我并不是绝对正确的,我不能100%肯定没有人会编辑这个类,而且种族条件是出了名的难以调试。这是一种防御机制