没有自我标识符的F#Val

Tal*_*eno 3 f#

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

lat*_*kin 5

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

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

因此,无论如何你都不会在自动道具中使用自我标识符,因为你要编写的唯一代码是无法触及实例成员的初始代码.

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

自动实现的属性是类型初始化的一部分,因此它们必须包含在任何其他成员定义之前,就像让绑定并在类型定义中进行绑定一样.请注意,初始化自动实现的属性的表达式仅在初始化时进行评估,而不是每次访问该属性时进行评估.此行为与显式实现的属性的行为形成对比.这实际上意味着初始化这些属性的代码被添加到类的构造函数中.

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

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@()
Run Code Online (Sandbox Code Playgroud)

编辑:值得注意的是,在即将到来的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() { }
}
Run Code Online (Sandbox Code Playgroud)