C# object initialization syntax in F#

后端 未结 3 759
攒了一身酷
攒了一身酷 2021-01-17 11:12

Please note: this question is not the same as this question.

I recently came across some C# syntax I hadn\'t previously encountered:

Is there any wa

相关标签:
3条回答
  • 2021-01-17 11:21

    F# 4.0 came out with a feature which might be useful to encapsulate @plinth's answer. It allows the creation of extension properties, which can be initialized in the constructor.

    0 讨论(0)
  • 2021-01-17 11:28

    Would it make sense to encapsulate the construction into a separate initializer function?

    let layerInit layer radius color offset opacity =
        do
           layer.ShadowRadius <- radius
           layer.ShadowColor <- color
           layer.ShadowOffset <- offset
           layer.ShadowOpacity <- opacity
        layer // I do this in case you want to use this fluently or pass in new Layer()
    

    Then use that in your code:

    let nameLabel = new UILabel ( TextColor = UIColor.White )
    layerInit nameLabel.Layer 3.0f UIColor.Black.CGColor new System.Drawing.SizeF(0.0f,1.0f) 0.5f |> ignore
    
    0 讨论(0)
  • 2021-01-17 11:38

    I don't think F# allows setting nested properties during initialization. A workaround, assuming you're the author of the API, is to pass the entire object to the constructor. This eliminates the need for getter and setter with different accessibilities and makes for much cleaner F# code overall.

    type Two() =
        member val Test = "" with get, set
    
    type One(twoProperty) =
        member val TwoProperty = twoProperty
    
    let test = One(Two(Test="foo"))
    

    As you mentioned in your comment, you could create a helper function accepting various properties as optional parameters. A type extension would work well for this:

    type UILayer with
        member this.Configure(?shadowRadius, ?shadowColor, ?shadowOffset, ?shadowOpacity) = 
            this.ShadowRadius <- defaultArg shadowRadius this.ShadowRadius
            this.ShadowColor <- defaultArg shadowColor this.ShadowColor
            this.ShadowOffset <- defaultArg shadowOffset this.ShadowOffset
            this.ShadowOpacity <- defaultArg shadowOpacity this.ShadowOpacity
    
    let nameLabel = UILabel(TextColor=UIColor.White)
    nameLabel.Layer.Configure(
        shadowRadius=3.0f, 
        shadowColor=UIColor.Black.CGColor, 
        shadowOffset=SizeF(0.0f, 1.0f), 
        shadowOpacity=0.5f)
    
    0 讨论(0)
提交回复
热议问题