在我们的许多项目中,我看到了一些自定义集合或容器类,它们包含某种通用集合,例如:一个List(of T)
课程。
它们通常有一个GetXXX方法,它返回自定义集合类使用的任何类型的IEnumerable,因此可以使用foreach循环迭代内部集合。
e.g。
public IEnumerable<UploadState> GetStates
{
get
{
return new List<UploadState>(m_states);
}
}
我的问题是,这些类应该实现IEnumerable
接口,并在List本身上调用GetEnumerator
。
是否有首选方式,还是由开发人员负责?
答案 0 :(得分:2)
我会这样做:
public IEnumerable<UploadState> GetStates
{
get
{
foreach (var state in m_states) {
yield return state;
}
}
}
它更干净,您的用户没有得到他们不应该的列表(毕竟他们可以将它转换为List<T>
)并且您不需要创建List<T>
对象
编辑:误解了这个问题。我认为如果该类是一个集合,它应该实现IEnumerable<T>
。
答案 1 :(得分:2)
如果您的类是自定义集合类,则是,它应该实现IEnumerable<T>
。在这种情况下,内部列表的公共属性将是多余的。想象一个简单的课程:
public class People : IEnumerable<Person>
{
List<Person> persons = new List<Person>();
public IEnumerator<Person> GetEnumerator()
{
return persons.GetEnumerator();
}
}
但是,如果您的类不能像集合那样行事,那么为其元素提供公共IEnumerable
属性:
public class Flight
{
List<Person> passengers = new List<Person>();
public IEnumerable<Person> Passengers
{
get { return passengers; }
}
}
无论如何,开发人员总是应该选择合适的设计。
答案 2 :(得分:1)
请在代码示例中考虑创建新列表。我不知道m_states
是什么,但如果这是一个值类型集合,则创建原始列表的克隆。通过这种方式,可以从调用者添加/删除/更新元素操纵返回列表。 没有影响原始数据。
如果m_states
是引用类型,则仍然会创建一个新列表,调用者可以再次操作添加/删除/ 否更新元素(它是参考!)而不影响原始数据。
IEnumerable<T>
怎么样,它只是一种使返回类型通用的方法,而不是与List<T>
类型强耦合。
答案 3 :(得分:0)
您应该根据System.Collections.ObjectModel
命名空间中的一个类派生自定义集合类。它们已经包含IEnumerable<T>
和非通用IEnumerable
接口的实现。
答案 4 :(得分:0)
我认为如果您新实现的类的行为与列表的行为相同,则无需实现它。如果你需要某种自定义逻辑,那取决于你想做什么;你可以继承列表,也可以实现IEnumerable。这取决于要实现的目标。
答案 5 :(得分:0)
您可能想要检查一下: http://www.codeproject.com/Articles/4074/Using-IEnumerator-and-IEnumerable-in-the-NET-Frame
我还没有完整阅读,但我认为这可以回答你的问题。