C#中的混凝土二传手抽象吸气剂

时间:2010-12-15 08:21:58

标签: c#

我正在尝试为实现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摘要。有没有允许这个的语法?

7 个答案:

答案 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。所以你可以有两个选择:

  1. 私有地实现IList并为索引器提供公共抽象getter(如果我可以有两个索引器,则不是100%确定)。
  2. Indexer getter将调用一个抽象方法,如GetItem。

答案 6 :(得分:-2)

你不需要一个二传手

public abstract object this[int index] { get; }