Jacek Dominiak
Jacek Dominiak

Reputation: 877

f# type attribute access

Is there any way one can access the type attribute by using it's name represented in a string. Something along the lines of:

type B = {FirstName:string; LastName:string} 
let b = { FirstName="Bob"; LastName="Smith" }  
b.``"FirstName"``

The reason being that I want to access the type dynamically based on the xml based map.

Upvotes: 3

Views: 555

Answers (1)

scrwtp
scrwtp

Reputation: 13577

This is something you can do via reflection. In addition to the general .NET reflection API, F# comes with a small reflection library, Microsoft.FSharp.Reflection, that provides some utility functions for constructing and decomposing basic F# types like records.

You can get PropertyInfos of all the record fields using:

FSharpType.GetRecordFields(typeof<B>)

Then you can decompose a record into an array of values and put them back into a record like this:

let fields = FSharpValue.GetRecordFields(b)
let b' = FSharpValue.MakeRecord(typeof<B>, fields) :?> B

You can build your own persistence library on top of that, but this is for the most part a solved problem. I think Json.NET should handle serializing records out of the box now, for sure there's an xml equivalent as well.

F# also offers a distinct alternative in the form of type providers. If you want your xmls to "drive" how your types look - particularly if you're accessing external sources that communicate through xml - you may want to look into FSharp.Data and XmlProvider. They give a very similar vibe to what you're doing in your example - you point the type provider to an xml sample and it generates a type corresponding to the xml's structure during the compilation. So you can just use the xml node names as regular field names in F# code, in a statically typed fashion.

Type providers are good for scripting and exploratory programming, since they save you time having to declare and update type definitions. But when building a more long-lasting application, you may find it desirable to use explicitly defined types as the representation.

Upvotes: 5

Related Questions