c# 为相同的 class 实现两个枚举器
c# Implementing two enumerators for the same class
好的,下面是基本代码:
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 }
我是否必须子class 每个元素并在每个元素上实现 IEnumerable 接口,然后将这些作为属性包括在内?我误解了 IEnumerable 接口吗?我知道列表 class 有它自己的枚举器,所以我可以做类似
的事情
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 接口,所以也许我遗漏了一些明显的东西。
不要公开 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();
}
}
对 a
和 b
的任何更改都将反映在 A
和 B
中。
另请注意,虽然您可以将 List<T>
转换为 IReadOnlyList<T>
,但调用代码可以将其转换回 List<T>
。上面的方法 returns a ReadOnlyCollection<T>
提供了防止转换回可变集合类型的保护措施。
readonly
关键字仅确保您以后不会用其他内容替换对 a
和 b
的引用。
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();}}
}
这样你甚至不必初始化它,也不需要任何类型的设置
好的,下面是基本代码:
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 }
我是否必须子class 每个元素并在每个元素上实现 IEnumerable 接口,然后将这些作为属性包括在内?我误解了 IEnumerable 接口吗?我知道列表 class 有它自己的枚举器,所以我可以做类似
的事情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 接口,所以也许我遗漏了一些明显的东西。
不要公开 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();
}
}
对 a
和 b
的任何更改都将反映在 A
和 B
中。
另请注意,虽然您可以将 List<T>
转换为 IReadOnlyList<T>
,但调用代码可以将其转换回 List<T>
。上面的方法 returns a ReadOnlyCollection<T>
提供了防止转换回可变集合类型的保护措施。
readonly
关键字仅确保您以后不会用其他内容替换对 a
和 b
的引用。
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();}}
}
这样你甚至不必初始化它,也不需要任何类型的设置