1

此代码有效

  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 识别为正在定义的静态方法....

4

3 回答 3

3

此限制是公共语言规范 (CLS) 的一部分,并非特定于 F#。

根据CLI 规范,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
    }
}

但是您将无法从 F# 或 C# 等 CLS 兼容语言访问上述类的所有成员。

于 2013-05-16T21:01:10.290 回答
1

member不遵循相同的规则let,一个类的所有成员一次都可用(事实上,在某些极端情况下,它是一个有用的技巧来拉取复杂的相互依赖关系)。

不幸的是,在 .NET 语言中解析类成员的规则通常很复杂,静态和实例之间的区别有时很难区分。

我不知道是否有针对此确切问题的语法修复,但通常避免使用相同的名称总是如您所提到的那样有效。

于 2013-05-16T18:07:50.440 回答
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
于 2013-05-17T08:32:06.980 回答