Just a note on the covariance of the IReadOnlyList<out T>
type (similar to vasil oreshenski's answer).
If you decide to have:
public XmlPatternTree(IReadOnlyList<string> nodeNames,
IReadOnlyList<IReadOnlyList<string>> attributeNames,
IReadOnlyList<IReadOnlyList<string>> attributeValues) : this()
{
NodeNames = nodeNames;
AttributeNames = attributeNames;
AttributeValues = attributeValues;
}
public IReadOnlyList<string> NodeNames { get; private set; }
public IReadOnlyList<IReadOnlyList<string>> AttributeNames { get; private set; }
public IReadOnlyList<IReadOnlyList<string>> AttributeValues { get; private set; }
public int Depth => NodeNames.Count;
in your class, then the covariance mentioned means you can use reference conversions, and not any wrapping inside another class, as in:
var nn = new List<string>();
var an = new List<string[]>();
var av = new List<string[]>();
// populate 'nn', 'an', and 'av'
// the following compiles with no wrapper class:
var tree = new XmlPatternTree(nn, an, av);
Of course, people can cast the interfaces back to the actual types, like List<string[]>
, and modify the collections without using reflection, if they guess that the type is really that list of arrays. However, that would be quite malignant, so you could assume it is no problem if only "good" people use your class
PS! What I said and coded above with IReadOnlyList<out T>
could just as well have been done with IReadOnlyCollection<out T>
since it is covariant ("out
") as well. You would just not have the indexer access on the properties (such as var name = tree.AttrbuteNames[idx1][idx2]
). But then you could use HashSet<>
and similar which are not IReadOnlyList<>
.