简体   繁体   English

IList的 <IList<T> &gt;到IReadonlyCollection <IReadonlyCollection<T> &gt;

[英]IList<IList<T>> to IReadonlyCollection<IReadonlyCollection<T>>

I have a list of string array and I would like to make both collection read-only. 我有一个字符串数组列表,我想将两个集合都设为只读。

So I have this code: 所以我有这段代码:

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

My issue is that AttributeNames and AttributeValues assignments causes a compilation error, it seems that I can create a ReadonlyCollection of ReadonlyCollection from a non-readonly collection of non-readonly objects. 我的问题是AttributeNames和AttributeValues分配导致编译错误,似乎我可以从非只读对象的非只读集合中创建ReadonlyCollection的ReadonlyCollection。

Is there something I can do other than looping over all the values and add them in the list ? 除了遍历所有值并将它们添加到列表中之外,我还能做些什么吗?

Thanks 谢谢

If you change your type from IList<string> to just List<string> , then this should work: 如果将类型从IList<string>更改为List<string> ,则应该可以:

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

If you can't modify your method signature (ie you have to keep IList<string> ), then you can do this: 如果您不能修改方法签名(即必须保留IList<string> ),则可以执行以下操作:

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

If the version of the .net framework is greater then 4.0 the generic version of List<> implements the IReadOnlyCollection<> interface. 如果.net框架的版本大于4.0,则List<>的通用版本将实现IReadOnlyCollection<>接口。 If it is more convenient for you, you can change your signature from IList<ILIst<>> to List<List<>> and should work fine. 如果更方便,则可以将签名从IList<ILIst<>>更改为List<List<>>并且应该可以正常工作。

 AttributeNames = attributeNames;
 AttributeValues = attributeValues;

Just a note on the covariance of the IReadOnlyList<out T> type (similar to vasil oreshenski's answer). 只需注意一下IReadOnlyList<out T>类型的协方差(类似于vasil oreshenski的答案)。

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. 当然,如果人们猜测类型实际上就是数组列表,那么人们可以将接口转换回实际类型,如List<string[]> ,并修改集合而不使用反射。 However, that would be quite malignant, so you could assume it is no problem if only "good" people use your class 但是,那将是非常恶性的,因此,如果只有“好人”使用您的班级,您可以认为这没问题

PS! 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. 我上面用IReadOnlyList<out T>说和编码的内容也可以使用IReadOnlyCollection<out T>因为它也是协变的(“ out ”)。 You would just not have the indexer access on the properties (such as var name = tree.AttrbuteNames[idx1][idx2] ). 您将只对属性没有索引器访问权限(例如var name = tree.AttrbuteNames[idx1][idx2] )。 But then you could use HashSet<> and similar which are not IReadOnlyList<> . 但是然后您可以使用HashSet<>和类似的东西,它们不是IReadOnlyList<>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM