【问题标题】:c# Implementing two enumerators for the same classc#为同一个类实现两个枚举器
【发布时间】:2015-08-22 00:45:59
【问题描述】:

好的,下面是基本代码:

class foo
{
    String name;
    int property;
}

class bar
{
    private List<foo> a;
    private List<foo> b;
}

我想这样做,以便调用代码可以遍历任一列表,但我希望保护它们不被编辑。我已经研究过实现 IEnumarable 接口,但问题是它需要一个“GetEnumerable”定义,但我想要两个不同的枚举器。例如,我想能够说

foreach(foo in bar.getA())
{ //do stuff }

然后

foreach(foo in bar.getB())
{ //do stuff }

我是否必须对每个元素进行子类化并在每个元素上实现 IEnumerable 接口,然后将 THOSE 作为属性包含在内?我误解了 IEnumerable 接口吗?我知道 List 类有它自己的 Enumerator,所以我可以做类似的事情

class bar
{
    private List<foo> a;
    private List<foo> b;

    public IEnumerator<foo> getAEnumerator()
    {  return a.GetEnumerator();

    public IEnumerator<foo> getBEnumerator()
    {  return b.GetEnumerator();

}

但是我的 for 循环看起来像这样:

bar x = new bar();
IEnumerator<foo> y = x.getAEnumerator();
while (y.moveNext())
{
    foo z = y.Current;
} 

所以我失去了“foreach”的可读性。

有没有办法在不公开这些列表的情况下对这些列表使用“foreach”?我仍在尝试了解 IENumerable 接口,所以也许我遗漏了一些明显的东西。

【问题讨论】:

标签: c# list ienumerable ienumerator


【解决方案1】:

不要公开List&lt;T&gt;,而是公开其他内容,例如IReadOnlyList&lt;T&gt;

class bar
{
    private readonly List<foo> a = new List<foo>();
    private readonly List<foo> b = new List<foo>();

    public IReadOnlyList<foo> A { get; private set; }
    public IReadOnlyList<foo> B { get; private set; }

    public bar()
    {
        A = a.AsReadOnly();
        B = b.AsReadOnly();
    }
}

ab 的任何更改都将反映在AB 中。

还请注意,虽然您可以将 List&lt;T&gt; 强制转换为 IReadOnlyList&lt;T&gt;,但调用代码可以将其强制转换回 List&lt;T&gt;。上述方法返回一个ReadOnlyCollection&lt;T&gt;,它提供了防止强制转换回可变集合类型的安全措施。

readonly 关键字仅确保您以后不会用其他内容替换对 ab 的引用。

【讨论】:

  • 是的;正是我正在寻找的。直到现在我才意识到我对 Lists 知之甚少。是时候阅读了。
【解决方案2】:
class bar
{
    private readonly List<foo> a = new List<foo>();
    private readonly List<foo> b = new List<foo>();

    public IReadOnlyList<foo> A { get {return a.AsReadOnly();}}
    public IReadOnlyList<foo> B { get {return b.AsReadOnly();}}

}

这样你甚至不必初始化它,也不需要任何类型的设置

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    相关资源
    最近更新 更多