F#类和结构中主要构造函数之间的行为差​​异?

Hil*_*key 9 f# visual-studio-2013

如果我在Visual Studio Express 2013中尝试此类型定义,则会收到错误消息:

type Foo(bar : int) =
   struct
      member x.bar = bar
   end
Run Code Online (Sandbox Code Playgroud)

如果我改变它以使它成为一个类,我不会得到任何错误:

type Foo(bar : int) =
   class
      member x.bar = bar
   end
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

The member 'bar' can not be defined because the name 'bar' clashes with the field 'bar' in this type or module"
Run Code Online (Sandbox Code Playgroud)

如果我稍微更改构造函数参数的名称,则错误消失.我理解CLR结构和类之间的差异,但我不太明白这种行为差异的原因.有人能解释一下吗?

我大多问的是,如果答案消除了我对F#的更深层次的误解.谢谢.

Dan*_*iel 5

虽然我无法在规范中找到相关的引用,但是对反编译器的一些实验表明,结构体上的主构造函数参数总是被编译为具有相同名称的字段.对于类,使用更复杂的规则集(参见§8.6.1.3)来确定其编译形式,其中包括在与成员冲突时更改字段名称.

比较这个结构和类的编译形式:

type S(bar: int) = struct end

type C(bar: int) =
    member x.bar = bar
Run Code Online (Sandbox Code Playgroud)
public class C
{
    internal int bar@12;

    public int bar
    {
        get
        {
            return this.bar@12;
        }
    }

    public C(int bar)
    {
        this.bar@12 = bar;
    }
}

public struct S : IEquatable<Program.S>, IStructuralEquatable, IComparable<Program.S>, IComparable, IStructuralComparable
{
    internal int bar;

    public S(int bar)
    {
        this.bar = bar;
    }
}
Run Code Online (Sandbox Code Playgroud)

struct的主构造函数参数被编译为一个字段(并已分配!),即使它未被使用.另一方面,该类允许具有相同名称的成员和参数.不可否认,这并不能解释原因,但可能有助于澄清观察到的行为.