views:

1126

answers:

3

I am writing a custom ConfigurationElementCollection for a custom ConfigurationHandler in C#.NET 3.5 and I am wanting to expose the IEnumerator as a generic IEnumerator.

What would be the best way to achieve this?

I am currently using the code:

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

Cheers

A: 

IEnumerable<T> already derives from IEnumerable so there's no need to do any conversion. You can simply cast to it...well actually it's implicit no cast necessary.

IEnumerable<T> enumerable = GetGenericFromSomewhere();
IEnumerable sadOldEnumerable = enumerable;
return sadOldEnumerable.GetEnumerator();

Going the other way round isn't much more difficult with LINQ:

var fancyEnumerable = list.OfType<GenericObject>();
return fancyEnumerable.GetEnumerator();
Paul Alexander
My bad missed the generic part to my method definition
zonkflut
You are confusing IEnumerable and IEnumerator. IEnumerable<T> derives from IEnumerable and IEnumerator<T> derives from IEnumerator. It doesn't make much sense to say "IEnumerable<T> theEnumerator" because an enumerable is not an enumerator.
Matt Olenik
casting does not work as the in the parent object the collection is stored in an ArrayList.
zonkflut
Yep - read it too quickly. But the answer still applies. I'll fix it to reflect the correct classes.
Paul Alexander
It does not work for the case:var genericEnumerator = (IEnumerator<int>)new ArrayList { 1 }.GetEnumerator();throws exception:System.InvalidCastException: Unable to cast object of type 'ArrayListEnumeratorSimple' to type 'System.Collections.Generic.IEnumerator`1[System.Int32]'.
zonkflut
You can't cast from non-generic to generic. You have to use the OfType method mentioned in the second portion. You can only cast from generic to non-generic.
Paul Alexander
+10  A: 

I don't believe there's anything in the framework, but you could easily write one:

IEnumerator<T> Cast<T>(IEnumerator iterator)
{
    while (iterator.MoveNext())
    {
        yield return (T) iterator.Current;
    }
}

In your case, however, it's easier - the existing class already implements IEnumerable, so you can use the Cast method in LINQ:

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

Alternatively, clients could just call Cast<T> themselves :)

Jon Skeet
Can't you just return the Enumerator from cast?return this.Cast<T>().GetEnumerator();
flq
Frank: You're absolutely right :)
Jon Skeet
Thats it thanks. Thankyou all for your responses.
zonkflut
A: 

You can use OfType<T> and Cast<T>.

public static IEnumerable Digits()
{
    return new[]{1, 15, 68, 1235, 12390, 1239};
}

var enumerable = Digits().OfType<int>();
foreach (var item in enumerable)
    // var is here an int. Without the OfType<int(), it would be an object
    Console.WriteLine(i);

To get an IEnumerator<T> instead of an IEnumerable<T> you can just make a call to GetEnumerator()

var enumerator = Digits().OfType<int>().GetEnumerator();
Svish