Pregunta

Consider the following classes:

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... */ }
    }
}

Is there something about the interfaces implemented by List and ReadOnlyCollection that would allow one-way type casting rather than recreating of the list to other concrete implementations?

The objective is to allow public read-only access but also protected add-only, indexed-based access to derived classes.

¿Fue útil?

Solución

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];
    }
}

I don't like returning read-only collections, because IEnumerable is a read-only interface which hides implementation from consumer. Some can argue, that consumer may cast IEnumerable to list and add new items, but that means two things:

  • consumer violates API you provided
  • you can't stop consumer from reflection usage
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top