私有列表<t>与公共IEnumerable <t> vs ReadOnlyCollection <t> </t> </t> </t>

时间:2014-01-02 10:32:02

标签: c# .net inheritance collections readonly

考虑以下课程:

public abstract class Token
{
    private List<Token> _Tokens { get; set; }

    // ReadOnly public is mandatory. How to give protected add-only, index-based access?
    public ReadOnlyCollection<Token> Tokens { get { return (this._Tokens.AsReadOnly()); } }

    // AddOnly for derived classes.
    protected Token AddToken (Token token) { this._Tokens.Add(token); return (token); }
}

public class ParenthesesToken: Token
{
    // This method is called frequently from public code.
    public void Parse ()
    {
        // Good enough.
        base.AddToken(...);

        // Is a call to List<T>.AsReadOnly() necessary?
        // Add-only, indexed-based access is mandatory here. IEnumerable<T> will not do.
        foreach (var token in this.Tokens) { /* Do something... */ }
    }
}

List和ReadOnlyCollection实现的接口是否允许单向类型转换而不是将列表重新创建到其他具体实现?

目标是允许公共只读访问,但也保护对派生类的仅添加,基于索引的访问。

1 个答案:

答案 0 :(得分:3)

public abstract class Token
{
    private List<Token> _tokens { get; set; }

    public IEnumerable<Token> Tokens 
    { 
       get { return _tokens; } 
    }

    protected Token AddToken (Token token) 
    { 
       _tokens.Add(token); 
       return token; 
    }

    protected Token GetTokenAt(int index)
    {
        return _tokens[index];
    }
}

我不喜欢返回只读集合,因为IEnumerable是一个只读接口,它隐藏了来自使用者的实现。有人可能会说,消费者可能会IEnumerable来列出并添加新项目,但这意味着两件事:

  • 消费者违反了您提供的API
  • 你不能阻止消费者反思使用