有没有办法保护类变量不被修改在函数之外

时间:2015-03-05 19:06:18

标签: c# class private friend

我有一个我想要保护的卷变量,除非此人调用某个函数。有没有办法让它只能由该函数修改,而不是在类中创建私有类。我想创建私人课程是个好主意,但如果其他人有不同的方法,我会感兴趣。绝不允许AudioPlayer在不调用SetVolume的情况下更改音量。这是我在这里的代码,但我想知道人们是否有不同的方式。

public class AudioPlayer
{
    private class VolumeManager
    {
        private AudioPlayer mAudioPlayer;
        public VolumeManager(AudioPlayer audioPlayer)
        {
            mAudioPlayer = audioPlayer;
        }

        private float volume;

        public void SetVolume(float _volume)
        {
            volume = _volume;

            //Do other necessary things that must happen when volume is changed
            //This is the point of the question
            mAudioPlayer.ModifyChannelVolume(Volume);
        }
        public float GetVolume()
        {
            return volume;
        }
    }

    private VolumeManager mVolumeManager;
    public AudioPlayer()
    {
        mVolumeManager = new VolumeManager(this);
    }

    public void ModifyVolume(float volume)
    {
        mVolumeManager.SetVolume(volume);
    }
}

2 个答案:

答案 0 :(得分:3)

正如我所看到的那样,问题在于,即使使用私人领域,想要直接分配到该领域仍然有点直观和自然。我们希望确保不会发生这种情况。在这种情况下,我建议将其作为一个属性而不是一个字段来构建,并且只是对仅分配给该属性进行管理:

public class AudioPlayer
{

    public float Volume 
    {
       get { return _volume_NeverSetThisDirectly;}
       set 
       {
           _volume = value;
           //Do other necessary things that must happen when volume is changed
           ModifyChannelVolume(_volume_NeverSetThisDirectly);
       }
    }
    [Browsable(false)]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    [EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    private float _volume_NeverSetThisDirectly; //Never assign to this directly!
}

这不会强制到你所要求的程度,但它确实会让人们在这个班级中以正确的方式使用价值的直观而自然的方式,而不是错误的方式。这也是维护代码和复杂性要少得多的问题。这些属性的添加在很大程度上不会影响已经在这个班级工作的人,但由于我们正在改变使用社会压力而不是技术禁令,我们所拥有的警告信号越多越好。

当你发现一个奇怪的情况,你想要改变音量字段而没有发生所有其他事情时,这也为你提供了一个开放,你可以这样做而不需要对私人做一些奇怪的事情类实例。

答案 1 :(得分:0)

也许,您可以将Volume变量声明为private,并且仅修改函数中的变量,并使用属性公开Volume字段。

private float Volume;  
public float pVolume
    {
        get
        {
            return Volume;
        }
    }