从派生类设置只读对象

时间:2013-06-21 06:32:42

标签: c# .net inheritance readonly readonly-collection

我正在编写一个我们公司其他开发人员将使用的库。状态机基类具有ReadOnlyCollection<T>个允许的状态等。开发人员需要从该类继承并设置允许的状态。

我想限制它们在派生类的构造函数中初始化ReadOnlyCollection<T>,而不能在以后修改它。

如果我将ReadOnlyCollection<T>声明为基类中的只读属性,那么这不起作用,因为它无法在派生类的构造函数中修改。

我认为这是一个不那么罕见的场景。任何优雅的方式来实现这一点,让开发人员覆盖ReadOnlyCollection<T>

2 个答案:

答案 0 :(得分:3)

不要让他们自己初始化。使您的基类构造函数将集合作为参数:

public class BaseClass
{
      protected readonly Collection someObject;
      public BaseClass(Collection object)
      {
            someObject = object
      }
}

所以现在当调用派生类构造函数时,它也应该使用集合对象调用基类构造函数 否则将是编译时错误。这将确保集合在构造函数中初始化,而不是在其他位置。

public class Derivedclass : BaseClass
{
      public DerivedClass() : base(/*pass the collection object here*/)
      {
      }
}

还有一个陷阱,如果你得到了一个集合的引用,你仍然可以通过调用派生类中的集合的Add或remove方法来修改集合,只有你不能重新初始化它的readonly。

答案 1 :(得分:0)

它必须是ReadOnlyCollection吗? 我会选择IEnumerable。

这可以这样做,类似于srsyogesh的回答:

public abstract class StateMachine
{
    public StateMachine(params States[] allowedStates)
    {
        _allowedStates = allowedStates;
    }

    private readonly IEnumerable<States> _allowedStates;

    public IEnumerable<States> AllowedStates
    {
        get { return _allowedStates; }
    }
}

public class DerivedStateMachine : StateMachine
{
    public DerivedStateMachine()
        : base(States.State1, States.State2)
    {

    }
}

当然,人们仍然可以将财产转回阵列并进行更改,但那将是一种犯罪行为。取决于您的受众。为了更加防弹,你可以,而不是只返回字段,迭代内容:

    public IEnumerable<States> AllowedStates
    {
        get
        {
            foreach(var state in _allowedStates)
                yield return state;
        }
    }