2017-01-25 198 views
0

我有一个字符串数组的列表,我想使这两个集合都是只读的。IList <IList<T>>到IReadonlyCollection <IReadonlyCollection <T>>

所以我有这样的代码:

public XmlPatternTree(IList<string> nodeNames, IList<IList<string>> attributeNames, 
     IList<IList<string>> attributeValues) : this() 
    { 
     NodeNames = new ReadOnlyCollection<string>(nodeNames); 
     AttributeNames = new ReadOnlyCollection<ReadOnlyCollection<string>>(); 
     AttributeValues = attributeValues; 
     Depth = NodeNames.Count; 
    } 

我的问题是,AttributeNames和AttributeValues分配导致编译错误,看来我可以从非只读的非只读集合创建ReadonlyCollection的ReadonlyCollection对象。

除了循环遍历所有的值并将它们添加到列表中,我还能做些什么吗?

感谢

回答

2

如果从IList<string>改变你的类型,只是List<string>,那么这应该工作:

attributeNames.Select((x) => x.AsReadOnly()).ToList().AsReadOnly(); 

如果你不能修改你的方法的签名(即你保持IList<string> ),那么你可以这样做:

attributeNames.Select((x) => x.ToList().AsReadOnly()).ToList().AsReadOnly(); 
1

如果版本t他的.net框架大于4.0,List<>的通用版本实现了IReadOnlyCollection<>接口。 如果您更方便,您可以将您的签名从IList<ILIst<>>更改为List<List<>>,并且应该可以正常工作。

AttributeNames = attributeNames; 
AttributeValues = attributeValues; 
1

IReadOnlyList<out T>型(类似瓦西oreshenski的答案)的协方差刚一说明。

如果您决定:

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; 
在类

,届时提及协方差意味着你可以使用引用转换,并没有任何包装另一个类内,如:

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); 

当然,人们可以将界面转换回实际类型,如List<string[]>,并且如果他们猜测类型实际上是数组列表,那么可以在不使用反射的情况下修改集合。但是,这将是非常恶劣的,所以如果只有“好”的人使用你的班级,你可以认为这是没有问题的

PS!我之前说的并且编码在IReadOnlyList<out T>之上的编码也可以用IReadOnlyCollection<out T>完成,因为它是协变的(“out”)。你只是没有索引器访问属性(如var name = tree.AttrbuteNames[idx1][idx2])。但是,那么你可以使用HashSet<>和类似的不是IReadOnlyList<>

相关问题