从字符串创建有区别的联合用例 [英] Create Discriminated Union Case from String
问题描述
我正在尝试从字符串创建DU案例.我看到的唯一方法是通过Microsoft.FSharp.Reflection.FSharpType.GetUnionCases
枚举DU的情况,然后选择与字符串匹配的UnionCase
(通过使用.Name
),然后通过使用<从中得出实际的DU情况c3>.
I'm trying to create DU cases from strings. The only way I can see doing this is by enumerating over the DU cases via Microsoft.FSharp.Reflection.FSharpType.GetUnionCases
and then picking the UnionCase
that matches the string (by using .Name
) and then making the actual DU case out of that by using FSharpValue.MakeUnion
.
难道没有一种更简单/更优雅的方法吗?在我的场景中,我有一个带有数百个关键字案例的DU.我必须从文件中读取字符串(关键字),并从中找出类型.我通过将案例放入地图中进行了一些优化",但我希望这样做会有更好的方法.
Isn't there an easier/more elegant way of doing this? In my scenario I have a DU with a couple of hundred cases for keywords. I have to read the strings (keywords) from a file and make the types out of them. I did some "optimization" by putting the cases into a Map but I was hoping there'd be a better way of doing this.
例如,我有以下内容:
type Keyword =
| FOO
| BAR
| BAZ
| BLAH
let mkKeywords (file: string) =
use sr = new StreamReader(file)
let caseMap =
FSharpType.GetUnionCases(typeof<Keyword>)
|> Array.map (fun c -> (c.Name, FSharpValue.MakeUnion(c, [||]) :?> Keyword))
|> Map.ofArray
[
while not sr.EndOfStream do
let l = sr.ReadLine().Trim()
match caseMap.TryFind l with
| Some c -> yield c
| None -> failwith <| "Could not find keyword: " + l
]
推荐答案
我发现了此方便的代码段.
I found this handy code snippet...
open Microsoft.FSharp.Reflection
let toString (x:'a) =
match FSharpValue.GetUnionFields(x, typeof<'a>) with
| case, _ -> case.Name
let fromString<'a> (s:string) =
match FSharpType.GetUnionCases typeof<'a> |> Array.filter (fun case -> case.Name = s) with
|[|case|] -> Some(FSharpValue.MakeUnion(case,[||]) :?> 'a)
|_ -> None
...这使得轻松将两行代码附加到任何DU ...
... which makes it easy to tack on two lines of code to any DU...
type A = X|Y|Z with
override this.ToString() = FSharpUtils.toString this
static member fromString s = FSharpUtils.fromString<A> s
这篇关于从字符串创建有区别的联合用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!