我正在编写一个我们公司其他开发人员将使用的库。状态机基类具有ReadOnlyCollection<T>
个允许的状态等。开发人员需要从该类继承并设置允许的状态。
我想限制它们在派生类的构造函数中初始化ReadOnlyCollection<T>
,而不能在以后修改它。
如果我将ReadOnlyCollection<T>
声明为基类中的只读属性,那么这不起作用,因为它无法在派生类的构造函数中修改。
我认为这是一个不那么罕见的场景。任何优雅的方式来实现这一点,让开发人员覆盖ReadOnlyCollection<T>
?
答案 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;
}
}