实现IEnumerable<'T>当基类实现IEnumerable时

时间:2011-12-08 21:55:40

标签: f# ienumerable

是否有一种简洁的方法在基类型实现非泛型IEnumerable<'T>的类型中实现IEnumerable?我正在使用下面的mkEnumerator函数来执行此操作,但似乎过多了。

open System
open System.Collections.Generic
open System.Configuration

let mkEnumerator<'T> (e : System.Collections.IEnumerator) =
  { new IEnumerator<'T> with
      member __.Current = e.Current |> unbox
    interface System.Collections.IEnumerator with
      member __.Current = e.Current
      member __.MoveNext() = e.MoveNext()
      member __.Reset() = e.Reset()
    interface IDisposable with
      member __.Dispose() =
        match e with
        | :? IDisposable as d -> d.Dispose()
        | _ -> () }

type MyConfigElement() = 
  inherit ConfigurationElement()

type MyConfigCollection() =
  inherit ConfigurationElementCollection()
  override __.CreateNewElement() = Unchecked.defaultof<_>
  override __.GetElementKey(_) = Unchecked.defaultof<_>
  interface IEnumerable<MyConfigElement> with
    member __.GetEnumerator() = mkEnumerator<MyConfigElement> (base.GetEnumerator())

更新

根据desco的建议,我现在正在使用:

type MyConfigCollection() =
  inherit ConfigurationElementCollection()
  ...
  interface IEnumerable<MyConfigElement> with
    member __.GetEnumerator() = (Seq.cast<MyConfigElement> this).GetEnumerator()

2 个答案:

答案 0 :(得分:4)

Brian的建议缩短版:

let mkEnum<'T> (ie : System.Collections.IEnumerable) = (Seq.cast<'T> ie).GetEnumerator()

答案 1 :(得分:3)

我认为你的方式看起来最好。我想这更简洁(我没有尝试端对端以确保它有效):

let mkEnum<'T>(ie : System.Collections.IEnumerable) 
                       : System.Collections.Generic.IEnumerator<'T> =
    (seq { for x in ie -> unbox x }).GetEnumerator()

但我想知道它是否会分配更多。

正如@desco所指出的,这更短:

let mkEnum<'T> ie = (Seq.cast<'T>(ie)).GetEnumerator()