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 }