Reputation: 9825
This code works
type UserNode(myid:int64, labeled:bool) =
static member SkypeId (x:UserNode) = x.SkypeI
member this.SkypeI = myid
Yet this one does not : "SkypeId is not an instance method"
The only difference I think I have is the "d" and the end of SkypeI
type UserNode(myid:int64, labeled:bool) =
static member SkypeId (x:UserNode) = x.SkypeId
member this.SkypeId = myid
What am I missing here... ?
Ok oddly enough it recognizes SkypeId as the static method being defined....
Upvotes: 1
Views: 279
Reputation: 61
In c# it would look like this:
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; }
}
}
We got two errors: - The type 'xxx.UserNode' already contains a definition for 'SkypeId'; - And inside static method "Cannot convert expression type 'method group' to return type int". As Leaf Garland wrote there can't be method and property with same name. But overloaded method works:
type UserNode(myid:int64, labeled:bool) =
static member SkypeId (x:UserNode) = x.SkypeId()
member this.SkypeId() = myid
Upvotes: 1
Reputation: 3697
This restriction is part of the Common Language Specification (CLS), it is not specific to F#.
From the CLI specification, CLS Rule 5 states that:
All names introduced in a CLS-compliant scope shall be distinct independent of kind, except where the names are identical and resolved via overloading. That is, while the CTS allows a single type to use the same name for a method and a field, the CLS does not.
So the Common Type System (CTS) does allow this, as the following compilable IL shows
.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
}
}
But you wont be able to access all the members of the above class from a CLS compliant language like F# or C#.
Upvotes: 3
Reputation: 19223
member
does not follow the same rules as let
, all members of a class are available at one time (in fact it is a useful trick to pull of complex interdependencies in some edge cases).
Unfortunately the rules for resolving class members are often complex in .NET languages and the distinction between static and instance is sometimes hard to come by.
I don't know offhand if there is a syntax fix for this exact issue but in general avoiding identical names always works as you mentioned.
Upvotes: 1