2013-05-16 84 views
0

此代码的工作实例方法警告

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为被定义的静态方法....

+2

'this'会指当前正在执行的情况下,这不会有'SkypeId',因为它是一个静态成员,而不是一个实例成员。 – jbabey

+0

你真的需要静态方法吗?能够执行'UserNode.SkypeId x'似乎很奇怪,因为你不会获得太多的语法。 – Guvante

+0

确实,但我觉得奇怪的是“x”。将不会范围的方法名称.... – nicolas

回答

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#。

+0

IL示例的完整源代码[这里](https://gist.github.com/leafgarland/5595181) –

+0

有趣,谢谢你的参考。 – nicolas

1

member不遵循相同的规则为let,类的所有成员都可以在同一时间(实际上它是一个在某些边缘情况下拉动复杂的相互依赖的有用技巧)。

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

我不知道如果有针对这个确切问题的语法修复,但总的来说避免相同的名称总是如你所说的那样工作。

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“。 由于叶加兰写在那里不能有同名的方法和属性。 但重载方法的工作原理:

type UserNode(myid:int64, labeled:bool) = 
    static member SkypeId (x:UserNode) = x.SkypeId() 

    member this.SkypeId() = myid 
相关问题