此代码有效
type UserNode(myid:int64, labeled:bool) =
static member SkypeId (x:UserNode) = x.SkypeI
member this.SkypeI = myid
然而,这个不是:“SkypeId不是实例方法”
我认为我唯一的区别是“d”和SkypeI的终结
type UserNode(myid:int64, labeled:bool) =
static member SkypeId (x:UserNode) = x.SkypeId
member this.SkypeId = myid
我在这里想念的是什么......?
奇怪的是,它认为SkypeId是定义的静态方法....
答案 0 :(得分:2)
此限制是公共语言规范(CLS)的一部分,它不是特定于F#。
从CLI specification开始,CLS规则5规定:
在符合CLS的范围内引入的所有名称应独立于 种类,除非名称相同并通过重载解决。也就是说,虽然CTS允许单个类型对方法和字段使用相同的名称,但CLS不允许。
因此,通用类型系统(CTS)允许这样做,如下面的可编译IL显示
.class public auto ansi sealed Foo
extends [mscorlib]System.Object
{
.method public instance void .ctor()
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
.field public int32 Bar
.method public void Bar()
{
ldstr "Instance method"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method static public void Bar()
{
ldstr "Static method"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
但是您无法从符合CLS的语言(如F#或C#)访问上述类的所有成员。
答案 1 :(得分:1)
member
不遵循与let
相同的规则,类的所有成员一次都可用(事实上,它是在某些边缘情况下拉动复杂的相互依赖性的有用技巧)。
不幸的是,解析类成员的规则在.NET语言中通常很复杂,静态和实例之间的区别有时很难实现。
我不知道是否存在针对此确切问题的语法修复,但通常避免使用相同的名称始终如您所述。
答案 2 :(得分:1)
在c#中它看起来像这样:
public class UserNode
{
private readonly int _myid;
public UserNode(int myid)
{
_myid = myid;
}
public static int SkypeId(UserNode x)
{
return x.SkypeId;
}
public int SkypeId
{
get { return _myid; }
}
}
我们遇到两个错误: - 'xxx.UserNode'类型已经包含'SkypeId'的定义; - 并且内部静态方法“无法将表达式类型'方法组'转换为返回类型int”。 正如Leaf Garland写的那样,不能有同名的方法和属性。 但重载方法有效:
type UserNode(myid:int64, labeled:bool) =
static member SkypeId (x:UserNode) = x.SkypeId()
member this.SkypeId() = myid