没有自我标识符的F#Val

时间:2015-03-20 17:08:16

标签: f#

好奇为什么F#有: member val Foo = ... with get, set 省略自我标识符(例如this.)。 这仍然是一个实例属性。也许我是唯一一个在使用它时感到困惑的人。但只是打扰我,足以询问知道语言是如何定义的人。

1 个答案:

答案 0 :(得分:5)

使用这种语法,该属性几乎完全自动实现 - 您提供的只是初始化代码,它基本上作为构造函数的一部分运行。

F#最佳实践护栏之一就是它不允许您在实例完全初始化之前访问实例成员。 (哇,疯狂的想法,对吧?)。

所以你不会在自动道具中使用自我标识符,因为你要编写的唯一代码是不能触及实例成员的初始代码。

根据MSDN文档(强调我的):

  

自动实现的属性是初始化的一部分   一个类型,所以它们必须包含在任何其他成员定义之前,   就像让绑定并在类型定义中进行绑定一样。 请注意   初始化自动实现的属性的表达式   仅在初始化时评估,而不是每次属性时评估   被访问。这种行为与a的行为形成对比   明确实施的财产。这有效意味着什么   初始化这些属性的代码被添加到构造函数中   一堂课。

顺便说一句,如果你试图成为一个智能手机并使用类级自我标识符来解决这个问题,那么你在运行时仍然会爆炸:

type A() as this =
    member val X =
        this.Y + 10
        with get, set

    member this.Y = 42

let a = A()

System.InvalidOperationException: The initialization of an object or value resulted in an object or value being accessed recursively before it was fully initialized.
   at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.FailInit()
   at FSI_0013.A.get_Y()
   at FSI_0013.A..ctor()
   at <StartupCode$FSI_0014>.$FSI_0014.main@()

编辑值得注意的是,在即将到来的C#6中,他们现在也允许带有初始化程序的自动道具(更多F#功能被盗用于C#,震撼:-P),并且存在类似的限制你不能使用自我标识符:

class A
{
    // error CS0027: Keyword 'this' is not available in the current context
    public int X { get; set; } = this.Y + 10;
    public int Y = 42;
    public A() { }
}