reflection - Copying a discriminated union object -
i want make copy of object of discriminated union type, 1 or 2 particular fields assigned different values , other fields copied straight across.
the tricky part i'm trying write function this, keep working unchanged more cases added union, can't use match; instead, i'm looking solution uses reflection examine fields of particular case. here's have far on reverse side, extracting values object regardless of exact type:
let case = match fsharpvalue.getunionfields (a, typeof<term>) | info, _ -> info let unpack = let fields = list.ofseq ((case a).getfields ()) list.collect (fun (field: propertyinfo) -> let t = field.propertytype if t = typeof<term> [field.getvalue :?> term] elif t.isgenerictype && t.generictypearguments.[0] = typeof<term> field.getvalue :?> term list else [] ) fields and i'm trying write function starts off like:
let pack xs = let fields = list.ofseq ((case a).getfields ()) ... it occurred me try use memberwiseclone that's protected, can't used outside subclasses. i'm looking 'create new object of type, step through fields copying across or filling in values appropriate' though i'm not quite sure 'this type' be, since gettype doesn't work on discriminated unions. what's best way go it?
this lot easier looks (ignoring usual issues reflection).
you using fsharpvalue.getunionfields information union case , values of current union. there fsharpvalue.makeunion takes information , gives union value:
type term = | foo of int * string * bool let = foo(42, "answer", false) let case, values = fsharpvalue.getunionfields(a, typeof<term>) values.[2] <- box true fsharpvalue.makeunion(case, values) :?> term
Comments
Post a Comment