我正在尝试编写一个构造函数,该构造函数假定调用类中定义的方法并将结果分配给成员。在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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是我不知道该怎么做F#。
在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
Run Code Online (Sandbox Code Playgroud)
有两个缺点的例子:
// 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
Run Code Online (Sandbox Code Playgroud)
提到自引用类型时,我只想指出,使类型成为自引用类型会增加隐藏的开销:
// 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 ()
Run Code Online (Sandbox Code Playgroud)
反编译开销显示:
[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;
}
}
Run Code Online (Sandbox Code Playgroud)
F#中自引用类型的隐藏开销曾经使我性能下降(在某些用例中性能下降了50%)。
| 归档时间: |
|
| 查看次数: |
384 次 |
| 最近记录: |