.net - F# 比较区分联合的案例标识符

标签 .net reflection f# discriminated-union

有没有办法通过 F# 中的大小写标识符来比较受歧视的联合?

type MyUnion =
| MyString of string
| MyInt of int

let x = MyString("hello")
let y = MyString("bye")
let z = MyInt(25)

let compareCases a b =
// compareCases x y = true
// compareCases x z = false
// compareCases y z = false

如何以通用方式实现 compareCases 函数?

IE。类似于以下内容,但更通用(反射没问题):
let compareCases a b =
  match a with
  | MyString(_) -> match b with | MyString(_) -> true | _ -> false
  | MyInt(_) -> match b with | MyInt(_) -> true | _ -> false

最佳答案

使用 GetType() 的问题在于,如果您有 2 个“无数据”案例,它会失败。

这是一种方法:(编辑是因为之前的 UnionTagReader 没有被缓存)

type MyDU =
    | Case1
    | Case2
    | Case3 of int
    | Case4 of int

type TagReader<'T>() =
    let tr = 
        assert FSharpType.IsUnion(typeof<'T>)
        FSharpValue.PreComputeUnionTagReader(typeof<'T>, System.Reflection.BindingFlags.Public)

    member this.compareCase (x:'T) (y:'T) =
        (tr x) = (tr y)

let tr = TagReader<MyDU>()

let c1 = Case1
let c2 = Case2
let c3 = Case3(0)
let c3' = Case3(1)
let c4 = Case4(0)

assert (c1.GetType() = c2.GetType() )  //this is why you can not use GetType()

assert tr.compareCase c1 c1
assert not (tr.compareCase c1 c2)
assert tr.compareCase c3 c3'
assert not (tr.compareCase c3 c4)

关于.net - F# 比较区分联合的案例标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23796457/

相关文章:

f# - Async.BuildPrimitive 和 Async.Spawn 在哪里定义?

f# - F#: “fun”关键字是否必要?

.Net 缩略图在从移动设备创建时旋转图像

.net - DataGridView 最后一列标题后的空白

c# - 获取实现某个抽象类的所有类

Javascript反射,用字符串调用方法

.net - 任何复制 DebuggerDisplayAttribute 如何生成结果字符串的代码?

c# - LINQ to SQL 连接中的 DefaultIfEmpty() 导致重复

JAVA REFLECTION : java. lang.IllegalArgumentException:参数类型不匹配

c# - 为什么 LINQ (c#) 与 Seq (f#) 之间存在性能差异