如何将嵌套类的Property setter的访问仅限于外部类?

时间:2018-09-28 15:52:09

标签: c#

是否存在访问修饰符或其组合,以仅限制对外部类的访问?

对于下面嵌套类PanelFragment的{​​{1}}属性,我希望仅包含类ViewPagerPanels能够设置它(通过setter,我知道可以做到这一点也可以通过构造函数参数)。

public class ParcelView : MXActivityView<ParcelVM>, ViewPager.IOnPageChangeListener, IFragmentToViewPagerEvent
{
    private ViewPagerPanels _pagerPanels;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        _pagerPanels = new ViewPagerPanels(5);  // 5: magic number, put int constant

        _pagerPanels[0] = new ViewPagerPanels.PanelFragment(typeof(ViewA));
        // ...
    }

    private class ViewPagerPanels
    {
        public class PanelFragment
        {
            public Fragment Fragment { get; set; }
            // ?? - access modifer for set
            public int Position { get; private set; }
        }

        public readonly int PANEL_COUNT;

        private PanelFragment[] _panels;

        public ViewPagerPanels(int count)
        {
            PANEL_COUNT = count;
            _panels = new PanelFragment[PANEL_COUNT];
        }

        public PanelFragment this[int i]
        {
            get
            {
                return _panels[i];
            }

            set
            {
                _panels[i] = value;
                // !! - cannot access private property
                _panels[i].Position = i;
            }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

否,无法直接执行。限制最严格的访问修饰符private已经允许来自同一类的访问。其他所有修饰符都会进一步扩展该访问范围。

每个类,无论其嵌套的,私有的还是公共的,总是可以访问其声明的成员的每一个,而没有机会对其自身施加限制。我们可以得到的最接近的结果是使用一个readonly字段(或一个仅限getter的属性),该字段可防止声明的类在构造函数之外修改变量。但是对于可读写的版本,我们就没有选择了。

答案 1 :(得分:1)

有一种针对此类保护方案的解决方案。但是您应该进行以下更改;

1-用接口或抽象类替换您的具体类,并将其暴露给外界

2-使用具体的类实现此接口

3-通过工厂方法控制此类的创建

4-通过将接口(或抽象类)转换为私有类类型来设置属性

示例代码更改

public interface IPanelFragment
{
        Fragment Fragment { get; set; }
        // ?? - access modifer for set
        int Position { get; }
}

class PanelFragment : IPanelFragment
{
      public Fragment Fragment { get; set; }
      // ?? - access modifer for set
      public int Position { get; set; }
}

private IPanelFragment[] _panels;

public IPanelFragment CreateFragment(Fragment fragment, int pos)
{
     return new PanelFragment() { Fragment= fragment, Position = pos };
}

public IPanelFragment this[int i]
{
      get
      {
          return _panels[i];
      }

      set
      {
           _panels[i] = value;
           // !! - cannot access private property
           ((PanelFragment)_panels[i]).Position = i;
       }
  } 

答案 2 :(得分:0)

可能的解决方法

public int Position { get; private set; }
public int InitPosition { set { Position = value; } }

或者,取决于您对无吸气特性的哲学观点

public void InitPosition(int value) { Position = value; }