没有自我标识符的 F# Val

F# Val without Self Identifier

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

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

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

因此,无论如何,您在自动道具中没有用到自我标识符,因为您要编写的唯一代码是无法触及实例成员的初始化代码。

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

Automatically implemented properties are part of the initialization of a type, so they must be included before any other member definitions, just like let bindings and do bindings in a type definition. Note that the expression that initializes an automatically implemented property is only evaluated upon initialization, and not every time the property is accessed. This behavior is in contrast to the behavior of an explicitly implemented property. What this effectively means is that the code to initialize these properties is added to the constructor of a class.

顺便说一句,如果你想成为一个聪明人并使用 class 级别的自我标识符来解决这个问题,你仍然会在运行时崩溃:

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),并且有是一个类似的限制,你不能使用 self-identifier:

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() { }
}