Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a typed IEnumerable in C#?

I can do this:

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

But I can't do this?:

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

The error I get basically says I am missing the method

    public System.Collections.IEnumerator GetEnumerator();

When I change the return type of GetEnumerator() to that, then it tells me I am missing

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

If I try to include both, it tells me I have a duplicate method name.

How can I solve this?

like image 906
Matt Avatar asked Dec 03 '22 01:12

Matt


2 Answers

How can I solve this?

You need to use explicit interface implementation to implement at least one of the GetEnumerator methods, usually the non-generic one.

The code is simply with using directives :)

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();
    }
}
like image 153
Jon Skeet Avatar answered Dec 18 '22 09:12

Jon Skeet


Create both - e.g. an Explicit implementation that will call the Implicit implementation.

Example:

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();
    }
}
like image 25
Blachshma Avatar answered Dec 18 '22 08:12

Blachshma