[英]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.