N_A*_*N_A 14 c# f# object-initializers c#-to-f#
请注意:这个问题和这个问题不一样.
我最近遇到了一些我以前没有遇到过的C#语法:
在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" }};
Run Code Online (Sandbox Code Playgroud)
(注意TwoProperty
当setter是私有时初始化器中的初始化 - 它是在存储的对象上设置属性TwoProperty
,但不在Two
属性中存储新实例)
编辑:我最近在monotouch的构造函数中遇到了一些C#代码,如下所示:
nameLabel = new UILabel {
TextColor = UIColor.White,
Layer = {
ShadowRadius = 3,
ShadowColor = UIColor.Black.CGColor,
ShadowOffset = new System.Drawing.SizeF(0,1f),
ShadowOpacity = .5f
}
};
Run Code Online (Sandbox Code Playgroud)
我能想出的最好的F#翻译是这样的:
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
Run Code Online (Sandbox Code Playgroud)
这并不可怕,但它确实有更多的噪音与重复的layer
参考加上更多的命令和更少的声明.
我不认为F#允许在初始化期间设置嵌套属性.假设您是API的作者,解决方法是将整个对象传递给构造函数.这消除了对具有不同可访问性的getter和setter的需求,并使整个F#代码更加清晰.
type Two() =
member val Test = "" with get, set
type One(twoProperty) =
member val TwoProperty = twoProperty
let test = One(Two(Test="foo"))
Run Code Online (Sandbox Code Playgroud)
正如您在评论中提到的,您可以创建一个辅助函数,接受各种属性作为可选参数.类型扩展适用于此:
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)
Run Code Online (Sandbox Code Playgroud)
将构造封装到单独的初始化函数中是否有意义?
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()
Run Code Online (Sandbox Code Playgroud)
然后在您的代码中使用它:
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2326 次 |
最近记录: |