c#为同一个类实现两个枚举器

本文关键字:两个 枚举 同一个 实现 | 更新日期: 2023-09-27 17:54:08

好的,下面是基本代码:

class foo
{
    String name;
    int property;
}
class bar
{
    private List<foo> a;
    private List<foo> b;
}

我想让调用代码可以在任一列表上迭代,但我想保护它们不受编辑。我已经考虑过实现IEnumerable接口,但问题是它需要一个"GetEnumerable"定义,但我想要两个不同的枚举器。例如,我想说

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

然后

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

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

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<T>,而是公开其他东西,比如IReadOnlyList<T>

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<T>强制转换为IReadOnlyList<T>,但调用代码可以将其强制转换回List<T>。上面的方法返回一个ReadOnlyCollection<T>,它提供了一种防止强制转换回可变集合类型的保护。

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

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

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