如果我在Visual Studio Express 2013中尝试此类型定义,则会出现错误:
type Foo(bar : int) =
struct
member x.bar = bar
end
如果我更改它以便它是一个班级,我不会有任何错误:
type Foo(bar : int) =
class
member x.bar = bar
end
我得到的错误是:
The member 'bar' can not be defined because the name 'bar' clashes with the field 'bar' in this type or module"
如果稍微更改构造函数参数的名称,则错误消失。我理解CLR结构和类之间的差异,但我不太清楚这种行为差异的原因。谁能解释一下呢?
我主要是在问这个答案是否会消除我对F#的更深层次的误解。感谢。
答案 0 :(得分:5)
虽然我无法在规范中找到相关的参考资料,但是对反编译器的一些实验表明,结构体上的主要构造函数参数总是被编译为具有相同名称的字段。对于类,使用更复杂的规则集(请参阅§8.6.1.3)来确定其编译形式,其中包括在与成员冲突时更改字段名称。
比较此结构和类的编译形式:
type S(bar: int) = struct end
type C(bar: int) =
member x.bar = bar
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;
}
}
struct的主要构造函数参数被编译为一个字段(并已分配!),即使它未被使用。另一方面,该类允许具有相同名称的成员和参数。不可否认,这并不能解释为什么,但可能有助于澄清观察到的行为。