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 way to do this in F#?
class Two
{
public string Test { get; set; }
}
class One
{
public One()
{
TwoProperty = new Two();
}
public Two TwoProperty { get; private set; }
}
var test = new One(){ TwoProperty = { Test = "Test String" }};
(note the initialization of TwoProperty
in the initializer when the setter is private - it is setting a property on the object stored in TwoProperty
, but NOT storing a new instance of Two
in the property)
Edit: I recently came across some C# code in a constructor in monotouch like this:
nameLabel = new UILabel {
TextColor = UIColor.White,
Layer = {
ShadowRadius = 3,
ShadowColor = UIColor.Black.CGColor,
ShadowOffset = new System.Drawing.SizeF(0,1f),
ShadowOpacity = .5f
}
};
The best F# translation I could come up with was something like this:
let nameLabel = new UILabel ( TextColor = UIColor.White )
do let layer = nameLabel.Layer
layer.ShadowRadius <- 3.0f
layer.ShadowColor <- UIColor.Black.CGColor
layer.ShadowOffset <- new System.Drawing.SizeF(0.0f,1.0f)
layer.ShadowOpacity <- 0.5f
This isn't terrible, but it does have more noise with the repeated layer
reference plus its more imperative and less declarative.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With