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.