F# 将构造函数添加到记录?

aka*_*nom 3 .net f# datacontractserializer xmlserializer

基本上我想有一个单一的构造来处理序列化到 JSON 和格式化的 xml。Records 可以很好地序列化到 json 或从 json 序列化。但是 XmlSerializer 需要一个无参数的构造函数。我真的不想经历为这些构造构建类对象的练习(仅限原则)。我希望可以有一些快捷方式将无参数构造函数放到记录上(也许使用 wioth 语句或其他东西)。我无法让它表现 - 社区中有人有运气吗?

module JSONExample
    open System
    open System.IO 
    open System.Net 
    open System.Text 
    open System.Web 
    open System.Xml
    open System.Security.Authentication 
    open System.Runtime.Serialization //add assemnbly reference System.Runtime.Serialization System.Xml
    open System.Xml.Serialization
    open System.Collections.Generic 

    [<DataContract>]            
    type ChemicalElementRecord = { 
        [<XmlAttribute("name")>]
        [<field: DataMember(Name="name") >] 
        Name:string 

        [<XmlAttribute("name")>]
        [<field: DataMember(Name="boiling_point") >] 
        BoilingPoint:string 

        [<XmlAttribute("atomic-mass")>]
        [<field: DataMember(Name="atomic_mass") >] 
        AtomicMass:string 
    } 

    [<XmlRoot("freebase")>]
    [<DataContract>] 
    type FreebaseResultRecord = { 
        [<XmlAttribute("code")>]
        [<field: DataMember(Name="code") >] 
        Code:string 

        [<XmlArrayAttribute("results")>]
        [<XmlArrayItem(typeof<ChemicalElementRecord>, ElementName = "chemical-element")>]
        [<field: DataMember(Name="result") >] 
        Result: ChemicalElementRecord array

        [<XmlElement("message")>] 
        [<field: DataMember(Name="message") >] 
        Message:string 
        } 


    let getJsonFromWeb() = 
        let query = "[{'type':'/chemistry/chemical_element','name':null,'boiling_point':null,'atomic_mass':null}]"
        let query = query.Replace("'","\"") 
        let queryUrl = sprintf "http://api.freebase.com/api/service/mqlread?query=%s" "{\"query\":"+query+"}" 

        let request : HttpWebRequest = downcast WebRequest.Create(queryUrl) 
        request.Method <- "GET" 
        request.ContentType <- "application/x-www-form-urlencoded" 

        let response = request.GetResponse() 

        let result = 
            try 
                use reader = new StreamReader(response.GetResponseStream()) 
                reader.ReadToEnd(); 
            finally 
                response.Close() 

        let data = Encoding.Unicode.GetBytes(result); 
        let stream = new MemoryStream() 
        stream.Write(data, 0, data.Length); 
        stream.Position <- 0L 
        stream



    let test =
        // get some JSON from the web
        let stream = getJsonFromWeb()

        // convert the stream of JSON into an F# Record
        let JsonSerializer = Json.DataContractJsonSerializer(typeof<FreebaseResultRecord>) 
        let result: FreebaseResultRecord = downcast JsonSerializer.ReadObject(stream) 

        // save the Records to disk as JSON 
        use fs = new FileStream(@"C:\temp\freebase.json", FileMode.Create) 
        JsonSerializer.WriteObject(fs,result)
        fs.Close()

        // save the Records to disk as System Controlled XML
        let xmlSerializer = DataContractSerializer(typeof<FreebaseResultRecord>);
        use fs = new FileStream(@"C:\temp\freebase.xml", FileMode.Create) 
        xmlSerializer.WriteObject(fs,result)
        fs.Close()

        use fs = new FileStream(@"C:\temp\freebase-pretty.xml", FileMode.Create) 
        let xmlSerializer = XmlSerializer(typeof<FreebaseResultRecord>)
        xmlSerializer.Serialize(fs,result)
        fs.Close()

ignore(test)
Run Code Online (Sandbox Code Playgroud)

ben*_*ruk 5

Blockquote 我希望可以有一些快捷方式将无参数构造函数写入记录

通过使用CLIMutable属性,这在 F# 3.0 版中是可能的。将此添加到无参数构造函数和读/写属性(而不是只读属性)的记录类型中。