问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/20880941/private-listt-with-public-ienumerablet-vs-readonlycollectiont