IEnumeratorをIEnumeratorに変換する

IEnumerable<T>を実装するクラスで、
内部ではTでない別の型Uで保持しておきたいときがあるかも?

と思ってちょっと作ってみた。


Genericsを使った実行時型生成をなんとなく使ってみたりしてる。

public class AdapterEnumerator<TInput, TOutput> : IEnumerator<TOutput>
{
    private IEnumerator<TInput> originalEnumerator = null;
    private ObjectConverter<TInput, TOutput> converter = null;

    public AdapterEnumerator ( IEnumerator<TInput> enumerator )
    {
        this.originalEnumerator = enumerator;

        Type inputType = typeof( TInput );
        Type outputType = typeof( TOutput );

        if ( typeof( IConvertible ).IsAssignableFrom( inputType ) )
        {
            Type genericType = typeof( ConvertibleObjectConverter<,> ).MakeGenericType( inputType, outputType, inputType, outputType );

            this.converter = genericType.GetConstructor( Type.EmptyTypes ).Invoke( null ) as ObjectConverter<TInput, TOutput>;
        }
        else
        {
            this.converter = new ReflectionObjectConverter<TInput, TOutput>();
        }
    }

    internal abstract class ObjectConverter<_T, _U>
    {
        public ObjectConverter ()
        {
        }

        public abstract _U Convert ( _T value );
    }

    internal class ConvertibleObjectConverter<_T, _U> : ObjectConverter<_T, _U>
        where _T : IConvertible
    {
        public override _U Convert ( _T value )
        {
            return (_U)value.ToType( typeof( _U ), null );
        }
    }

    internal class ReflectionObjectConverter<_T, _U> : ObjectConverter<_T, _U>
    {
        System.ComponentModel.TypeConverter converter = null;

        public ReflectionObjectConverter ()
        {
            this.converter = System.ComponentModel.TypeDescriptor.GetConverter( typeof( _T ) );

            if ( null == converter )
            {
                throw new Exception( "type of _T has no TypeConverter." );
            }

            if ( false == converter.CanConvertTo( typeof( _U ) ) )
            {
                throw new Exception( "can not convert to type of _U from _T." );
            }
        }

        public override _U Convert ( _T value )
        {
            return (_U)this.converter.ConvertTo( value, typeof( _U ) );
        }
    }


    #region IEnumerator<TOutput> メンバ

    public TOutput Current
    {
        get
        {
            return this.converter.Convert( this.originalEnumerator.Current );
        }
    }

    #endregion

    #region IDisposable メンバ

    public void Dispose ()
    {
        this.originalEnumerator.Dispose();
    }

    #endregion

    #region IEnumerator メンバ

    object System.Collections.IEnumerator.Current
    {
        get
        {
            return this.Current;
        }
    }

    public bool MoveNext ()
    {
        return this.originalEnumerator.MoveNext();
    }

    public void Reset ()
    {
        this.originalEnumerator.Reset();
    }

    #endregion
}

public class AdapterEnumerable<TInput, TOutput> : IEnumerable<TOutput>
{
    private IEnumerable<TInput> originalCollection = null;

    public AdapterEnumerable ( IEnumerable<TInput> collection )
    {
        this.originalCollection = collection;
    }

    #region IEnumerable<TOutput> メンバ

    public IEnumerator<TOutput> GetEnumerator ()
    {
        return new AdapterEnumerator<TInput, TOutput>( this.originalCollection.GetEnumerator() );
    }

    #endregion

    #region IEnumerable メンバ

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
    {
        return this.GetEnumerator();
    }

    #endregion
}