我正在尝试为实现IList
的只读集合编写一个抽象基类。这样的基类应该实现set-indexer来抛出NotSupportedException
,但是将get-indexer保留为抽象。 C#是否允许这种情况?这是我到目前为止所做的:
public abstract class ReadOnlyList : IList {
public bool IsReadOnly { get { return true; } }
public object this[int index] {
get {
// there is nothing to put here! Ideally it would be left abstract.
throw new NotImplementedException();
}
set {
throw new NotSupportedException("The collection is read-only.");
}
}
// other members of IList ...
}
理想情况下,ReadOnlyList
能够实现setter,但保留getter摘要。有没有允许这个的语法?
答案 0 :(得分:8)
将工作委派给受保护的成员,然后根据所需的行为将其标记为抽象或虚拟。尝试这样的事情:
// implementor MUST override
protected abstract object IndexerGet(int index);
// implementor can override if he wants..
protected virtual void IndexerSet(int index, object value)
{
throw new NotSupportedException("The collection is read-only.");
}
public object this[int index] {
get {
return IndexerGet(index);
}
set {
IndexerSet(index, value);
}
}
答案 1 :(得分:2)
不,你不能拥有一个带有成员摘要的属性而另一个已实现。我要做的是将整个属性设置为抽象属性,并在继承者处重新定义它以做任何你想做的事。
答案 2 :(得分:0)
为什么不私下设置者?
public abstract class ReadOnlyList : IList
{
public bool IsReadOnly { get { return true; } }
public object this[int index]
{
get
{
// there is nothing to put here! Ideally it would be left abstract.
throw new NotImplementedException();
}
private set
{
// your private implementation
}
}
// other members of IList ...
}
答案 3 :(得分:0)
没有。如果你能找到一种方法,它确实打破了Liskov替代原则。
在此处阅读有关LSP的更多信息:Can you explain Liskov Substitution Principle with a good C# example?
答案 4 :(得分:0)
如果您希望它成为只读集合,那么为什么要实现IList
?
您应该改为IEnumerable
。
答案 5 :(得分:-1)
为什么你想要设置setter - 缺少setter会指示它的只读属性。
编辑:jgauffin指出,setter来自IList。所以你可以有两个选择:答案 6 :(得分:-2)
你不需要一个二传手
public abstract object this[int index] { get; }