【C#】IEnumerable<dynamic>の作り方
IEnumerable<dynamic>を継承するクラスを作成しようとするとビルド時に
動的なインターフェイス ‘System.Collections.Generic.IEnumerable<dynamic>’ を実装できません と表示される。
dynamicで受け取るオブジェクトがGetEnumeratorを実装していれば普通にforeachでいいんだけど、LINQが使えない。
特にCOM相互運用のオブジェクト、って言うか、ExcelのRange。あれはGetEnumeratorメソッドを持っているし、LINQをバリバリ使いたいオブジェクトの一つなので、IEnumerable<dynamic>を実装したラッパーを作りたいケースがまったくないわけでもない。
そう言った場合はIEnumerable<T>を継承してやればいい。
コード
public class IDynamicEnumrable<T> : IEnumerable<T> { private dynamic _range; public IDynamicEnumrable(dynamic range) { this._range = range; } public IEnumerator<T> GetEnumerator() { foreach (var cell in _range) yield return cell; } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return this.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } }
後はnew IDynamicEnumrable<dynamic>してやればOK。
まとめ
当然IEnumerable<T>で宣言しているためdynamic以外も指定出来てしまうので、型安全も何もないが、Tの代わりに渡したいdynamicの妥当性を検証するだけのクラス、もしくは使いたいプロパティだけを抽出するクラスを作成し、それに置き換えるという手法もある。(そっちの方がメジャーな手法らしい)
色々探してみると拡張メソッドでLINQのメソッドを新たに追加すると言う方法をとってる人がいたが、this objectを指定するのは、なんかこう、アレじゃないですかね?