Reflection 复制已识别的联合对象

Reflection 复制已识别的联合对象,reflection,f#,discriminated-union,Reflection,F#,Discriminated Union,我想制作一个对象的副本,该对象是有区别的并集类型,其中一个或两个特定字段指定了不同的值,其他字段直接复制 棘手的部分是,我正试图编写一个函数来实现这一点,它将保持工作不变,即使有更多的案例添加到联合中,所以我不能使用匹配;相反,我正在寻找一种解决方案,它使用反射来检查特定案例的字段。到目前为止,我在反面看到的是,从对象中提取值,而不管对象的确切类型: let case a = match FSharpValue.GetUnionFields (a, typeof<Term>)

我想制作一个对象的副本,该对象是有区别的并集类型,其中一个或两个特定字段指定了不同的值,其他字段直接复制

棘手的部分是,我正试图编写一个函数来实现这一点,它将保持工作不变,即使有更多的案例添加到联合中,所以我不能使用
匹配
;相反,我正在寻找一种解决方案,它使用反射来检查特定案例的字段。到目前为止,我在反面看到的是,从对象中提取值,而不管对象的确切类型:

let case a =
    match FSharpValue.GetUnionFields (a, typeof<Term>) with
    | info, _ ->
        info

let unpack a =
    let fields = List.ofSeq ((case a).GetFields ())
    List.collect
        (fun (field: PropertyInfo) ->
            let t = field.PropertyType
            if t = typeof<Term> then
                [field.GetValue a :?> Term]
            elif t.IsGenericType && t.GenericTypeArguments.[0] = typeof<Term> then
                field.GetValue a :?> Term list
            else
               []
        )
        fields

我突然想到尝试使用
MemberwiseClone
,但这是受保护的,所以不能在子类之外使用。我可能在寻找类似“创建此类型的新对象,然后逐步通过字段复制或适当地填充值”的内容,尽管我不太确定“此类型”是什么,因为
GetType
不适用于有区别的联合。最好的方法是什么?

这实际上比看起来容易得多(忽略了反射的常见问题)

您已经在使用
FSharpValue.GetUnionFields
获取有关联合案例的信息并获取当前联合的值。还有
FSharpValue.MakeUnion
,它获取这些信息并为您提供union值:

type Term = 
  | Foo of int * string * bool

let a = Foo(42, "answer", false)

let case, values = FSharpValue.GetUnionFields(a, typeof<Term>) 
values.[2] <- box true
FSharpValue.MakeUnion(case, values) :?> Term
类型术语=
|整数*字符串*布尔的Foo
设a=Foo(42,“回答”,假)
设为case,values=FSharpValue.GetUnionFields(a,typeof)
值[2]项

这实际上比看起来容易得多(忽略反射的常见问题)

您已经在使用
FSharpValue.GetUnionFields
获取有关联合案例的信息并获取当前联合的值。还有
FSharpValue.MakeUnion
,它获取这些信息并为您提供union值:

type Term = 
  | Foo of int * string * bool

let a = Foo(42, "answer", false)

let case, values = FSharpValue.GetUnionFields(a, typeof<Term>) 
values.[2] <- box true
FSharpValue.MakeUnion(case, values) :?> Term
类型术语=
|整数*字符串*布尔的Foo
设a=Foo(42,“回答”,假)
设为case,values=FSharpValue.GetUnionFields(a,typeof)
值[2]项