如何在C#中创建一个类型化的IEnumerable?

时间:2012-11-29 15:04:23

标签: c# .net interface iterator ienumerable

我可以这样做:

public class EnumerableTest : System.Collections.IEnumerable
{
    System.Collections.IEnumerable data;

    public EnumerableTest(System.Collections.IEnumerable d)
    {
        data = d;
    }

    public System.Collections.IEnumerator GetEnumerator()
    {
        foreach (object s in data)
        {
            yield return s;
        }
    }
}

但我不能这样做?:

public class EnumerableTestString : System.Collections.Generic.IEnumerable<string>
{
    System.Collections.Generic.IEnumerable<string> data;

    public EnumerableTestString(System.Collections.Generic.IEnumerable<string> d)
    {
        data = d;
    }

    public System.Collections.Generic.IEnumerator<string> GetEnumerator()
    {
        foreach (string s in data)
        {
            yield return s;
        }
    }
}

我得到的错误基本上说我错过了方法

    public System.Collections.IEnumerator GetEnumerator();

当我将GetEnumerator()的返回类型更改为该值时,它会告诉我我缺少

    public System.Collections.Generic.IEnumerator<string> GetEnumerator();

如果我尝试同时包含两者,它会告诉我我有一个重复的方法名称。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:9)

  

我该如何解决这个问题?

您需要使用explicit interface implementation来实现至少一种GetEnumerator方法,通常是非通用方法。

代码只是using指令:)

using System.Collections;
using System.Collections.Generic;

public class EnumerableTestString : IEnumerable<string>
{
    private IEnumerable<string> data;

    public EnumerableTestString(IEnumerable<string> d)
    {
        data = d;
    }

    public IEnumerator<string> GetEnumerator()
    {
        foreach (string s in data)
        {
            yield return s;
        }
    }

    // Explicit interface implementation for non-generic IEnumerable
    public IEnumerator IEnumerable.GetEnumerator()
    {
        // Delegate to the generic version
        return GetEnumerator();
    }
}

答案 1 :(得分:7)

创建两者 - 例如Explicit实施,将调用Implicit实施。

示例:

public class EnumerableTestString : System.Collections.Generic.IEnumerable<string>
{
    System.Collections.Generic.IEnumerable<string> data;

    public EnumerableTestString(System.Collections.Generic.IEnumerable<string> d)
    {
        data = d;
    }

    public System.Collections.Generic.IEnumerator<string> GetEnumerator()
    {
        foreach (string s in data)
        {
            yield return s;
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

答案 2 :(得分:1)

改为实施System.Collections.Generic.IEnumerable<T>

使用VS的智能标记执行此操作时,VS会自动创建两种方法。一个用于通用实现,另一个用于非泛型实现(因为IEnumerable<T>要求您实现IEnumerable

public class StringData : IEnumerable<string>
{
    ...

    #region IEnumerable<string> Members

    public IEnumerator<string> GetEnumerator()
    {
        foreach (string s in data) {
            yield return s;
        }
    }

    #endregion

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();  // Calls generic GetEnumerator
    }

    #endregion
}

请注意,非泛型方法是显式实现的,因此只能通过接口(IEnumerable x = ...; x.GetEnumerator())进行访问。它的目的是增加兼容性,并且是预先通用的c#版本(1.0,1.1)的残余。