首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IList<IList<T>>到IReadonlyCollection<IReadonlyCollection<T>>

IList<IList<T>>到IReadonlyCollection<IReadonlyCollection<T>>
EN

Stack Overflow用户
提问于 2017-01-25 15:49:44
回答 3查看 1.6K关注 0票数 1

我有一个字符串数组的列表,我希望这两个集合都是只读的。

所以我有个密码:

代码语言:javascript
复制
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。

除了循环所有的值并将它们添加到列表中之外,还有什么我可以做的吗?

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-25 15:52:56

如果您将您的类型从IList<string>更改为List<string>,则应该可以这样做:

代码语言:javascript
复制
attributeNames.Select((x) => x.AsReadOnly()).ToList().AsReadOnly();

如果无法修改方法签名(即必须保留IList<string>),则可以这样做:

代码语言:javascript
复制
attributeNames.Select((x) => x.ToList().AsReadOnly()).ToList().AsReadOnly();
票数 3
EN

Stack Overflow用户

发布于 2017-01-25 17:11:56

如果.net框架的版本更大,那么一般版本的List<>实现了IReadOnlyCollection<>接口。如果对您更方便,您可以将您的签名从IList<ILIst<>>更改为List<List<>>,并且应该可以正常工作。

代码语言:javascript
复制
 AttributeNames = attributeNames;
 AttributeValues = attributeValues;
票数 1
EN

Stack Overflow用户

发布于 2017-01-25 18:05:24

只需说明IReadOnlyList<out T>类型的协方差(类似于vasil oreshenski的答案)。

如果你决定拥有:

代码语言:javascript
复制
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;

在您的类中,所提到的协方差意味着您可以使用引用转换,而不是在另一个类中包装,如下所示:

代码语言:javascript
复制
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<>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41855890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档