【发布时间】:2019-07-09 05:23:40
【问题描述】:
我需要使用IReadOnlyList<T> 作为返回参数,因为它最符合我的需求,但正如您在下面的示例中所见,如果它不是真正只读的,您仍然可以修改它包装的列表。
using System.Collections.Generic;
using System.Collections.Immutable;
public class Test
{
public Test()
{
// return an IReadOnlyList that wraps a List, we can modify content
var list1 = GetList1();
if (list1 is List<Section> sections1) // can be true
{
sections1.Clear();
}
// return an IReadOnlyList that wraps an ImmutableArray, we cannot modify content
var list2 = GetList2();
if (list2 is List<Section> sections2) // never true
{
sections2.Clear();
}
}
public static IReadOnlyList<Section> GetList1()
{
return new List<Section> {new Section()};
}
public static IReadOnlyList<Section> GetList2()
{
return ImmutableArray.Create(new Section());
}
}
public struct Section
{
}
问题:
ImmutableArray<T> 看起来很棒,因为它是真正的只读的,唯一的事情是我不想/不需要公开返回允许生成副本的更改的 fully-featured class。
因此我坚持返回IReadOnlyList<T>,因为它的意图很简单,但我需要解决可能修改的列表问题。
问题:
将ImmutableArray<T> 作为IReadOnlyList<T> 返回是正确的方法吗?
如果没有,你能建议怎么做吗?
【问题讨论】:
-
请记住,
IReadOnlyList不会“包装”任何内容。它仍然是同一个列表对象。List实现IReadOnlyList这就是您访问它的方式。这就像在手机上盖上一个盖子,隐藏了屏幕的下半部分——它仍然是同一部手机。我想说ImmutableArray是解决此问题的正确方法,如果您想做的不仅仅是阻止人们意外修改列表。 -
好吧,用这个词不合适!
-
抱歉,我要编辑我的问题,因为我忘了提一些事情。
-
如果您不公开原始列表,您可以使用 AsReadOnly 方法,请参阅docs.microsoft.com/en-us/dotnet/api/…,它创建了一个只有只读集合方法的包装器。
-
@ckuri 看看docs.microsoft.com/en-us/dotnet/api/…中的备注部分