2017-01-25 195 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<>

相關問題