我正在尝试编写一个构造函数,该构造函数假设调用类中定义的方法并将结果赋给成员。在C#中,它将类似于:
public class Test
{
public int Value { get; private set;}
private static int SomeLogic(int a, int b)
{
return a + b;
}
public Test(int a, int b)
{
this.Value = SomeLogic(a,b);
}
}
但我不知道怎么做F#。
答案 0 :(得分:4)
在F#中实现此目的的两种不同方法示例:
type Test_UsesVal =
val value : int
new (a, b) = { value = someLogic a b }
member x.Value = x.value
type Test_Preferred (a : int, b: int) =
let value = someLogic a b
member x.Value = value
两个有缺点的例子:
// This type is default constructible and when using default ctor someLogic is not used
type Test_DefaultConstructible () =
let mutable value = 0
new (a, b) as x = Test_DefaultConstructible () then x.Value <- someLogic a b
member x.Value with get () = value and private set v = value <- v
// This type has 2 constructors and using single value ctor someLogic is not used
type Test_2Constructors (value : int) =
new (a, b) = Test_2Constructors (someLogic a b)
member x.Value with get () = value
由于提到了自引用类型,我只想指出一个类型自引用会增加隐藏的开销:
// Self referential types add hidden overhead
type Test_SelfReferential (a : int, b: int) as this =
let computeValue () = someLogic this.A this.B
member x.A = a
member x.B = b
member x.Value = computeValue ()
对开销节目进行了反编译:
[CompilationMapping(SourceConstructFlags.ObjectType)]
[Serializable]
public class Test_SelfReferential
{
internal int b;
internal int a;
// An extra field added
internal FSharpRef<Program.Test_SelfReferential> @this = new FSharpRef<Program.Test_SelfReferential>(null);
// An extra field added
internal int init@29-1;
public int A
{
get
{
// An extra check added in each method
if (this.init@29-1 < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
return this.a;
}
}
public int B
{
get
{
// An extra check added in each method
if (this.init@29-1 < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
return this.b;
}
}
public int Value
{
get
{
// An extra check added in each method
if (this.init@29-1 < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
return this.computeValue();
}
}
public Test_SelfReferential(int a, int b) : this()
{
this.a = a;
this.b = b;
// An extra init added in .ctor
this.@this.contents = this;
this.init@29-1 = 1;
}
[CompilerGenerated]
internal int computeValue()
{
// Extra checks added
return LanguagePrimitives.IntrinsicFunctions.CheckThis<Program.Test_SelfReferential>(this.@this.contents).A + LanguagePrimitives.IntrinsicFunctions.CheckThis<Program.Test_SelfReferential>(this.@this.contents).B;
}
}
F#中自引用类型的隐藏开销一度导致我的性能回归(在某些用例中性能下降了50%)。
答案 1 :(得分:3)
.swiper-button-next {
visibility: none;
}
.swiper-button-prev
{
visibility: none;
}
请注意,单个param构造函数是私有的。因此,让a = Test(1)是不可能的。
也许不需要setter或mutable字段。如果是的话......
type Test private (constructorParam) =
let mutable value = constructorParam
member this.Value
with get() = value
and private set newValue = value <- newValue
static member SomeLogic(a,b) = a+b
new(a,b) = Test(Test.SomeLogic(a,b))
let a = Test(1,2)
的引用:
答案 2 :(得分:1)
您可以在构造函数的开头使用as
绑定:
type SomeClass() as this =
do printfn this.Member1
member this.Member1 = "s"
您可以随意调用它:x
等,但我认为只使用this
就行了。
您可以在此处详细了解自我标识符:https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/classes
编辑:如果需要初始化该类型的任何私有字段,可以在构造函数中定义函数,在初始化中使用它,然后将其公开为公共成员:
let func x = ...
let field = func 0
member this.Method(x) = func x