【问题标题】:Is there a way to protect a class variable from being modified outside of a function有没有办法保护类变量不被函数外部修改
【发布时间】:2015-05-07 06:50:37
【问题描述】:

我有一个音量变量,我希望保护它不被修改,除非该人调用某个函数。除了在类中创建私有类之外,有没有办法使它只能由该函数修改。我想创建一个私人课程是个好主意,但如果其他人有不同的方法,我会很感兴趣。绝不应允许 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);
    }
}

【问题讨论】:

  • 为什么不把 Volume 设为私有浮动?
  • 我认为私人课程是这样做的唯一方法。但是在这种特殊情况下,为什么不把自定义代码放在 setter 中而不是单独的方法中呢?
  • 也许我遗漏了一些东西:“私有嵌套类”如何更改“私有设置器”访问权限?如果它是带有“私有设置器”的“公共非嵌套类”,它仍然无法访问。在属性的“集合”上使用私有修饰符已经实现了既定目标..
  • @Gandalf458 它必须使用 SetVolume,因为 setter 已经是私有的 .. 外部类型不是blessed-to-private-access。
  • @user2864740 我认为 OP 想知道是否有比将音量字段隐藏在私有嵌套类中更好的方法,即使当前方法已经确保音量只能通过 @ 设置mVolumeManager上的987654322@方法

标签: c# class private friend


【解决方案1】:

在我看来,问题在于即使使用私有字段,想要直接分配给该字段仍然有些直观和自然。我们要确保不会发生这种情况。在这种情况下,我建议将其构建为一个属性,而不是一个字段,并且只对属性进行分配:

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

这不会将其强制执行到您要求的程度,但它确实颠覆了某人在此类中工作的直观和自然方式,以正确的方式使用值,而不是错误的方式。维护的代码和复杂性也少了很多。属性的添加在很大程度上不会对已经在这个班级工作的人产生影响,但由于我们正在改变使用社会压力而不是技术禁令,所以我们拥有的警告标志越多越好。

这也为您在将来发现一个奇怪的情况提供了一个机会类实例。

【讨论】:

  • 我在一个快速工作的团队中。期望每个程序员在时间限制下阅读所有 cmets 是徒劳的。 :(
  • @Gandalf458 这与评论无关。它是关于“当Volume 更自然地出现时,谁真的会使用_volume”......特别是如果你从他们的智能提示中隐藏该字段。如果需要,您甚至可以将 _volume 的名称更改为 _volumeNeverSetDirectly 之类的名称。
  • 事实上,我想我会把它添加到答案中。
  • 将其命名为 neverSetDirectly 实际上是一个好主意,尤其是当变量对 Intellisense 隐藏时。我不知道如何隐藏它。
  • @Gandalf458 您只能在一定程度上保护您的代码免受其他团队成员的影响。如果您正在与会在不考虑影响的情况下进行更改的人一起工作,那么您可能希望在这样的“隐藏”代码上投入更少的时间,而是购买某种棒...
【解决方案2】:

也许,您可以将 Volume 变量声明为私有,并且只修改函数内的变量,并使用属性来公开 Volume 字段。

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

【讨论】:

    猜你喜欢
    • 2012-05-14
    • 2022-06-10
    • 2021-04-11
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 2010-12-01
    • 2018-05-11
    • 1970-01-01
    相关资源
    最近更新 更多