C# 将IEnumerator转换为通用IEnumerator的最佳方法是什么?

C# 将IEnumerator转换为通用IEnumerator的最佳方法是什么?,c#,enumeration,ienumerator,C#,Enumeration,Ienumerator,我正在为C#.NET 3.5中的自定义ConfigurationHandler编写一个自定义ConfigurationElementCollection,我希望将IEnumerator作为通用IEnumerator公开 实现这一目标的最佳方式是什么 我目前正在使用代码: public new IEnumerator<GenericObject> GetEnumerator() { var list = new List(); var baseEnum = base.GetEn

我正在为C#.NET 3.5中的自定义ConfigurationHandler编写一个自定义ConfigurationElementCollection,我希望将IEnumerator作为通用IEnumerator公开

实现这一目标的最佳方式是什么

我目前正在使用代码:

public new IEnumerator<GenericObject> GetEnumerator() { var list = new List(); var baseEnum = base.GetEnumerator(); while(baseEnum.MoveNext()) { var obj = baseEnum.Current as GenericObject; if (obj != null) list.Add(obj); } return list.GetEnumerator(); } 公共新IEnumerator GetEnumerator() { var list=新列表(); var baseEnum=base.GetEnumerator(); while(baseEnum.MoveNext()) { var obj=baseEnum.Current作为GenericObject; 如果(obj!=null) 列表。添加(obj); } 返回list.GetEnumerator(); } Cheers

IEnumerable
已从
IEnumerable
派生,因此无需进行任何转换。你可以简单地对它进行强制转换…实际上它是隐式的,不需要强制转换

IEnumerable<T> enumerable = GetGenericFromSomewhere();
IEnumerable sadOldEnumerable = enumerable;
return sadOldEnumerable.GetEnumerator();
IEnumerable enumerable=GetGenericFromSomewhere();
IEnumerable sadOldEnumerable=可枚举;
返回sadOldEnumerable.GetEnumerator();
对于LINQ来说,从另一个角度出发并不难:

var fancyEnumerable = list.OfType<GenericObject>();
return fancyEnumerable.GetEnumerator();
var fancyEnumerable=list.OfType();
返回fancyEnumerable.GetEnumerator();

我不相信框架中有任何内容,但您可以轻松编写一个:

IEnumerator<T> Cast<T>(IEnumerator iterator)
{
    while (iterator.MoveNext())
    {
        yield return (T) iterator.Current;
    }
}
IEnumerator转换(IEnumerator迭代器)
{
while(iterator.MoveNext())
{
产生返回(T)迭代器.Current;
}
}
从LINQ调用
Enumerable.Cast
,然后对结果调用
GetEnumerator()
,这很有诱惑力,但是如果类已经实现了
IEnumerable
,并且
T
是一个值类型,它充当了一个no-op,那么
GetEnumerator()
调用将递归并抛出一个
StackOverflowException
。使用
return foo.Cast.GetEnumerator()是安全的
foo
肯定是一个不同的对象时(它不会委托回这个对象),但如果不是这样,您可能最好使用上面的代码。

您可以使用
of type
Cast

这对我有用

IEnumerator<DataColumn> columnEnumerator = dt.Columns.Cast<DataColumn>().GetEnumerator();
IEnumerator columneumerator=dt.Columns.Cast().GetEnumerator();

我遇到了一些注释中提到的堆栈溢出问题。在我的例子中,这是因为GetEnumerator调用必须是base.GetEnumerator,否则您将在自己的GetEnumerator重新定义中循环

这是引发堆栈溢出的代码。foreach语句的使用调用了我试图重载的同一个GetEnumerator函数:

public new IEnumerator<T> GetEnumerator()
{
    foreach (T type in this)
    {
        yield return type;
    }
}
public新IEnumerator GetEnumerator()
{
foreach(此处为T类型)
{
收益型;
}
}
我最终得到了原始帖子的简化版本,因为你不需要使用列表持有者

public class ElementCollection<T> : ConfigurationElementCollection, IList<T>
    ...
    public new IEnumerator<T> GetEnumerator()
    {
        var baseEnum = base.GetEnumerator();
        while (baseEnum.MoveNext())
        {
            yield return baseEnum.Current as T;
        }
    }
    ...
}
公共类ElementCollection:ConfigurationElementCollection,IList
...
公共新IEnumerator GetEnumerator()
{
var baseEnum=base.GetEnumerator();
while(baseEnum.MoveNext())
{
产生返回baseEnum.Current作为T;
}
}
...
}

My bad错过了方法定义的泛型部分您混淆了IEnumerable和IEnumerator。IEnumerable派生自IEnumerable,IEnumerator派生自IEnumerator。说“IEnumerable theEnumerator”没有多大意义,因为可枚举项不是枚举数。强制转换不作为父对象工作,集合存储在ArrayList中。是的-读取它太快。但答案仍然适用。我将修复它以反映正确的类。它不适用于以下情况:var genericEnumerator=(IEnumerator)new ArrayList{1}.GetEnumerator();引发异常:System.InvalidCastException:无法将类型为“ArrayListEnumeratorSimple”的对象强制转换为类型为“System.Collections.Generic.IEnumerator`1[System.Int32]”。您不能从强制转换返回枚举数吗?返回此.Cast().GetEnumerator()@flq,Jon:我正在做
this.Cast().GetEnumerator()
解决方案,在相同的场景中(尽管我是从
IEnumerable
派生的),我得到了一个堆栈溢出。@Merlyn:我建议您发布一个简短但完整的示例作为另一个堆栈溢出问题。@Jon:您最初的收益率返回建议解决了我的问题,就像使用打字一样。但我还是可以发布一个问题。使用OfType()避免堆栈溢出异常,请参阅错误报告
public new IEnumerator<T> GetEnumerator()
{
    foreach (T type in this)
    {
        yield return type;
    }
}
public class ElementCollection<T> : ConfigurationElementCollection, IList<T>
    ...
    public new IEnumerator<T> GetEnumerator()
    {
        var baseEnum = base.GetEnumerator();
        while (baseEnum.MoveNext())
        {
            yield return baseEnum.Current as T;
        }
    }
    ...
}