C#从通用数组中获取通用IEnumerator

时间:2017-03-10 20:20:37

标签: c# generics multidimensional-array mono wrapper

我使用最新版本的Unity3D和MonoDevelop在C#中工作(我相信C#版本6目前在Unity中使用,但我可能错了)。

我目前的情况是,我有一个二维数组的包装类,我希望能够使用indI = [] indJ = [] for i in l: tmp = np.where(M == i) rd = randint(len(tmp)) indI.append(tmp[0][rd]) indJ.append(tmp[1][rd]) 迭代它,就像我在常规2D数组上一样。

foreach

但是,此public class CoordArray<T> : IEnumerable<T> { // ... some other members private T[,] arr; public CoordArray(int width, int height) { // ... other intialization arr = new T[height, width]; } public IEnumerator<T> GetEnumerator() { return arr.GetEnumerator(); } ... } public class Foo { public void Bar() { CoordArray<Poop> array = new CoordArray<Poop>(23,213); foreach(Poop p in array) DoSomething(p); } } 方法会在Unity中引发以下错误:

  

无法将GetEnumerator()类型隐式转换为System.Collections.IEnumerator。存在显式转换(您是否错过了演员?)

我在本网站上找到了一些类似问题的解决方案,并且我已尝试过:

System.Collections.Generic.IEnumerator<T>

但这再次给我一个错误:

  

无法将public IEnumerator<T> GetEnumerator() { return ((IEnumerable<T>) arr).GetEnumerator(); } 类型转换为T[,]

我也尝试过:

System.Collections.Generic.IEnumerable<T>

public IEnumerator<T> GetEnumerator() {
    return (IEnumerator<T>) arr.GetEnumerator();
}

public IEnumerator<T> GetEnumerator() {
    return arr.Cast<T>().GetEnumerator();
}

但这些都会引发以下错误:

  

public IEnumerator<T> GetEnumerator() { foreach (T element in arr) yield return element; } 未实现接口成员CoordArray<T>,并且最佳实现候选System.Collections.IEnumerable.GetEnumerator()返回类型CoordArray<T>.GetEnumerator()与接口成员返回类型System.Collections.Generic.IEnumerator<T>不匹配

如果我尝试:

System.Collections.IEnumerator

抛出完全相反的错误:

  

public IEnumerator GetEnumerator() { return arr.GetEnumerator(); } 未实现接口成员CoordArray<T>,并且最佳实现候选System.Collections.Generic.IEnumerable<T>.GetEnumerator()返回类型CoordArray<T>.GetEnumerator()与接口成员返回类型System.Collections.IEnumerator不匹配

和(很明显)它不允许我同时实施System.Collections.Generic.IEnumerator<T>IEnumerator GetEnumerator()

有没有办法从泛型数组中获取泛型迭代器?

2 个答案:

答案 0 :(得分:4)

问题是只有2d数组&#34;实现&#34;非通用IEnumerable。但您可以使用Cast方法获取IEnumerable<T>,然后从中获取IEnumerator<T>

public IEnumerator<T> GetEnumerator()
{
    return arr.Cast<T>().GetEnumerator();
}

确保已包含

using System.Linq;

如果由于某种原因Cast方法不可用,那么我想至少你可以使用C#迭代器方法(从2.0开始提供):

public IEnumerator<T> GetEnumerator()
{
    foreach (T element in arr)
        yield return element;
}

更新:您获得的新编译器错误不同。以上解决了我认为是你问题的目标的通用IEnumerable<T>.GetEnumerator()方法的实现。但是,由于IEnumerable<T>继承了IEnumerable,您还需要在您的类中实现非泛型GetEnumerator方法(我假设您已经这样做了)。它需要明确实现,因此将以下内容添加到您的类中:

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

答案 1 :(得分:1)

这样的事情会满足你的需求吗?

public class CoordArray<T> : IEnumerable<T>
{

    // ... some other members
    private T[,] arr;

    public CoordArray(int width, int height)
    {
        // ... other intialization
        arr = new T[height, width];
    }

    private IEnumerable<T> ArrAsEnumerableT
    {
        get
        {
            foreach (var elmt in arr)
                yield return elmt;
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return ArrAsEnumerableT.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ArrAsEnumerableT.GetEnumerator();
    }
}
相关问题