实现 IEnumerable当基类实现 IEnumerable 时

发布于 2024-12-20 07:40:36 字数 1379 浏览 2 评论 0原文

是否有一种简洁的方法可以在基类型实现非泛型 IEnumerable 的类型中实现 IEnumerable<'T>?我正在使用下面的 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()

Is there a succinct way to implement IEnumerable<'T> in a type whose base type implements the non-generic IEnumerable? I'm using the mkEnumerator function below to do it, but it seems excessive.

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

Update

Following desco's suggestion, I'm now using:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蔚蓝源自深海 2024-12-27 07:40:36

布莱恩建议的简短版本:

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

shorter version of Brian's suggestion:

let mkEnum<'T> (ie : System.Collections.IEnumerable) = (Seq.cast<'T> ie).GetEnumerator()
携余温的黄昏 2024-12-27 07:40:36

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

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

I think your way looks best. I guess this is more succinct (I have not tried it end-to-end to ensure it works):

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

but I wonder if it allocates more.

As is pointed out by @desco, this is even shorter:

let mkEnum<'T> ie = (Seq.cast<'T>(ie)).GetEnumerator()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文