是否可以在一个类中实现几个IEnumerable <t>?</t>

时间:2011-10-05 06:26:48

标签: c# .net ienumerable

我想做这样的事情:

class T : IEnumerable<string>, IEnumerable<int>
{
    string [] _strings = new string [20];
    int[] _ints = new int[20];

    public T() { }

    IEnumerator<string> IEnumerable<string>.GetEnumerator()
    {
        foreach (string str in _strings)
            yield return str;
    }

    IEnumerator<int> IEnumerable<int>.GetEnumerator()
    {
        foreach (int i in _ints)
            yield return i;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

}
//Using in code:
T t = new T();
foreach (int i in t)
   //to do something
foreach (string str in t)
   //to do stuff

我想知道有没有办法实现与否。可能有诡计吗?

2 个答案:

答案 0 :(得分:7)

您几乎设法实现这两个接口 - 您只需要更改非泛型实现,以显示您尝试委派的通用实现。例如:

IEnumerator IEnumerable.GetEnumerator()
{
    return ((IEnumerable<int>)this).GetEnumerator();
}

但是,因为您要实现多个IEnumerable<T>接口,所以需要在foreach循环中进行转换以显示要使用的接口:

T t = new T();
foreach (int i in (IEnumerable<int>) t)
   //to do something
foreach (string str in (IEnumerable<string>) t)

就个人而言,如果可能的话,我会强烈建议反对这样做 - 这会让阅读代码的人感到很困惑。

有关编译器如何处理表达式在foreach循环中进行迭代的详细信息,请参阅C#语言规范的第8.8.4节。

(通过使用一个接口的“普通”接口实现,你可以提供一种“默认” - 但我认为这不会真的让它变得更好。)

答案 1 :(得分:0)

我建议定义一些结构类型,其唯一的字段是类类型的实例,由stuct的构造函数初始化,其唯一的公共成员是GetEnumerator,并实现IEnumerable&lt; whatever&gt;通过在基类型上调用适当的方法。然后让你的根类实现一个返回适当结构的新实例的成员。

例如,如果您的类Foo有一个GetStringEnumerator方法返回一个实现IEnumerable&lt; String&gt;的类型,您可以让Foo.AsStrings返回一个结构FooStringEnumerable,其GetEnumerator方法名为Foo.GetStringEnumerator。

请注意,通过让您的可枚举事物成为结构而不是类,您将避免在常见情况下创建额外的对象实例,因为它在“for-each”循环中使用,因为vb和c#都是将鸭子键入GetEnumerator方法而不是强制转换为IEnumerable或IEnumerable&lt; T&gt;。