Syntaxe d’initialisation d’object C # en F #

Remarque: cette question n’est pas la même chose que cette question.

Je suis récemment tombé sur une syntaxe C # que je n’avais pas encore rencontrée:

Y a-t-il un moyen de faire cela en fa #?

class Two { public ssortingng Test { get; set; } } class One { public One() { TwoProperty = new Two(); } public Two TwoProperty { get; private set; } } var test = new One(){ TwoProperty = { Test = "Test Ssortingng" }}; 

(notez l’initialisation de TwoProperty dans l’initialiseur lorsque le séparateur est privé – il définit une propriété sur l’object stocké dans TwoProperty , mais ne stocke PAS une nouvelle instance de Two dans la propriété)

Edit: Je suis récemment tombé sur du code C # dans un constructeur monotouch comme ceci:

 nameLabel = new UILabel { TextColor = UIColor.White, Layer = { ShadowRadius = 3, ShadowColor = UIColor.Black.CGColor, ShadowOffset = new System.Drawing.SizeF(0,1f), ShadowOpacity = .5f } }; 

La meilleure traduction en F # que je pouvais trouver était quelque chose comme ceci:

 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 

Ce n’est pas terrible, mais il y a plus de bruit avec la référence de layer répétée plus son impératif et moins déclaratif.

Serait-il judicieux d’encapsuler la construction dans une fonction d’initialisation distincte?

 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() 

Alors utilisez ça dans votre 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 

Je ne pense pas que F # autorise la définition de propriétés nestedes lors de l’initialisation. Une solution de contournement, en supposant que vous soyez l’auteur de l’API, consiste à transmettre l’object entier au constructeur. Cela élimine le besoin de getter et de setter avec différentes accessibilités et permet d’obtenir un code F # beaucoup plus propre.

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

Comme vous l’avez mentionné dans votre commentaire , vous pouvez créer une fonction d’assistance acceptant diverses propriétés en tant que parameters facultatifs. Une extension de type fonctionnerait bien pour ceci:

 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) 

F # 4.0 est sorti avec une fonctionnalité qui pourrait être utile pour encapsuler la réponse de @ plinth. Il permet la création de propriétés d’extension pouvant être initialisées dans le constructeur.