4

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

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

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

我想这是一个不常见的场景。有什么优雅的方法可以实现这一点,而不是让开发人员覆盖ReadOnlyCollection<T>?

4

2 回答 2

4

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

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 方法来修改集合,唯一的问题是如果它是只读的,你不能重新初始化。

于 2013-06-21T06:38:53.730 回答
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)
    {

    }
}

当然,仍然可以将 Property 转换回数组并对其进行更改,但那将是一种犯罪行为。取决于你的听众。为了更加防弹,您可以迭代内容,而不仅仅是返回字段:

    public IEnumerable<States> AllowedStates
    {
        get
        {
            foreach(var state in _allowedStates)
                yield return state;
        }
    }
于 2013-06-21T07:46:15.397 回答