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

4

我可以做到这一点:

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个回答

9

我该如何解决这个问题?

你需要使用显式接口实现来实现至少一个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();
    }
}

7

创建两个 - 一个是显式实现,将调用隐式实现。

示例:

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();
    }
}

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)之前的遗留物。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接