C#实现泛型IEnumerable
我一直想知道是否可以说State
类实现IEnumerable<Person>
和IEnumerable<City>
所以我可以通过foreach以及所有的城市,让所有居住在该州的人。它甚至不会编译这样说:Error 1 'ConsoleApplication1.City' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'
(怪异)...以下是代码:C#实现泛型IEnumerable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Person
{
}
class City : IEnumerable<Person>
{
// City has citizens:
Person[] citizens;
IEnumerator<Person> IEnumerable<Person>.GetEnumerator()
{
foreach (Person p in citizens)
yield return p;
}
}
class State : IEnumerable<Person>, IEnumerable<City>
{
// State has cities:
City[] cities;
IEnumerator<Person> IEnumerable<Person>.GetEnumerator()
{
foreach (City c in cities)
foreach (Person p in c)
yield return p;
}
IEnumerator<City> IEnumerable<City>.GetEnumerator()
{
foreach (City c in cities)
yield return c;
}
}
class Program
{
static void Main(string[] args)
{
State s = new State();
foreach (Person p in s) ;
foreach (City c in s) ;
}
}
}
问题是IEnumerable<T>
还需要您实施IEnumerable
(非通用版本)。您需要实施GetEnumerator()
调用。
这就是说,这将变得非常棘手,因为你需要确定哪些东西要枚举State
。我个人而言,避免在同一个类实现IEnumerable<T>
两次,而不是返回枚举的方法:
class State : IEnumerable<City>
{
public IEnumerable<Person> GetPeople()
{
// return people...
在一般情况下,我认为,试图使事情是两个不同的类型的枚举是一个真正的设计缺陷。这将是更好的有国家实施更象:
public class State
{
public IEnumerable<City> Cities { get { // return cities...
public IEnumerable<People> People { get { // return people...
这将要求您更改您的使用情况(略),更像:
foreach(Person person in theState.People)
{
// ....
个人而言,我认为这将是State
和City
的更好方法。我写这篇文章,如:
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Person
{
}
class City
{
// City has citizens:
Person[] citizens;
public IEnumerable<Person> People
{
get
{
return citizens;
}
}
}
class State : IEnumerable<Person>, IEnumerable<City>
{
// State has cities:
City[] cities;
public IEnumerable<City> Cities
{
get
{
return cities;
}
}
public IEnumerable<Person> AllPeople
{
get
{
return Cities.SelectMany(c => c.People);
}
}
}
class Program
{
static void Main(string[] args)
{
State s = new State();
foreach (Person p in s.AllPeople) { /* Do something */ }
foreach (City c in s.Cities) { /* Do something */ }
}
}
}
我觉得这是很多更清晰 - 作为一个城市有人,但它本身不是,人物等
您需要实现非通用变种,太! System.Collections.IEnumerable是没有泛型类型参数的一个!
为System.Collections.Generic.IEnumerable.GetEnumerator添加一个显式接口实现 - 并使其抛出异常 - 您无法正确实现非通用接口。
我应该如何实施它,因为我想要返回所有人或所有城市 – 2012-08-08 20:06:32
@NikolasJíša:请参阅Reed的解决方法 – Sebastian 2012-08-08 20:08:13
这实际上是一个有趣的问题,因为里德和塞巴斯蒂安都指出,你也需要实现非泛型方法。但是,您只能实现一次,并且您有两个需要的接口。我认为一个更好的设计可能没有状态实现IEnumerable,但有两个属性人民和城市,揭露IEnumerables。我认为这也将是一个稍微更方便(可发现)的API。
谢谢大家,我现在得到了我想知道的。 – 2012-08-08 20:17:11