如何迭代枚举,并抛出obj

Ste*_*ing 3 ienumerable enums f#

如何在F#中枚举枚举/类型告诉我们如何在F#中获取.Net枚举类型的枚举器:

使用: Enum.GetValues(typeof<MyType>)

但是,当我使用它时,我发现了一个限制.我可以解决这个限制,但我正在寻找一种更好的方法.

问题是该解决方案返回一个.Net数组对象,但要使用它我们需要转换它,并且该转换对于迭代来说是不实用的.

type Colors =
| Red = 0
| Blue = 1
| Green = 2

// Strongly typed function, to show the 'obj' in real use
let isFavorite color = color = Colors.Green

// Iterate over the Enum (Colors)
for color in Enum.GetValues(typeof<Colors>) do
    printfn "Color %A. Is Favorite -> %b" color (isFavorite color)  // <-- Need to cast
Run Code Online (Sandbox Code Playgroud)

(IsFavorite color)提高之间的冲突类型Colors和(预期)obj(实际)

这很容易解决:

for obj in Enum.GetValues(typeof<Colors>) do
    printfn "Color %A. Is Favorite -> %b" obj (isFavorite (unbox<Colors> obj))
Run Code Online (Sandbox Code Playgroud)

但是,如果一个人需要(unbox<Colors> obj)在几个地方呢?

本地let color = ...就足够了,但理想情况下,我们会使用一个返回a的枚举表达式seq<Colors>.

我已经能够构建该表达式,但它是:a.难以建立,和b.啰嗦.

let colorsSeq = 
     Seq.cast (Enum.GetValues(typeof<Colors>)) 
     |> Seq.map (fun o -> unbox<Colors> o)

for color in colorsSeq do
    printfn "Color %A. Is Favorite -> %b" color (isFavorite color)
Run Code Online (Sandbox Code Playgroud)

有更好的表达吗?

Mar*_*ann 5

Enum.GetValues是一个古老的BCL的API,所以没有什么可以做这件事......我不认为你可以得到你在想什么显著比你已经拥有简洁的方式,但你可以减少这一点:

let colorsSeq = Enum.GetValues(typeof<Colors>) |> Seq.cast<Colors>
Run Code Online (Sandbox Code Playgroud)

如果你需要做很多这样的事情,你可以考虑将它打包成一个通用函数:

module Enum = 
    let values<'a> = Enum.GetValues(typeof<'a>) |> Seq.cast<'a>
Run Code Online (Sandbox Code Playgroud)

这将使您能够像这样使用它:

for color in Enum.values<Colors> do
    printfn "Color %A. Is Favorite -> %b" color (isFavorite color)
Run Code Online (Sandbox Code Playgroud)

  • 你不需要`map unbox <'a>`:你可以直接`seq.cast <'a>`. (3认同)

Joh*_*mer 4

这似乎是最简单的版本:

let t : Colors seq = unbox (Enum.GetValues(typeof<Colors>)) 
Run Code Online (Sandbox Code Playgroud)