One of the first questions I came up with yesterday when digging into F# was this: what does an F# type look like to C#? As a noob, that’s an interesting question to me. Of course, being a noob, I had no clue about how to create a custom type. So, I asked Google what an F# type definition looked like, then massaged that until I had something that I might not completely understand, but that does show the problem at hand. I created a lame Name class that only supports a first name. Boo-yah!
First, I went to an existing file in an F# library called stuff.fs. There, I added the following class:
type Name(fname : string) =
let mutable fName = fname
member this.FName with get() = fName
and set(x) = fName <- x
For you C# heads out there, let’s look at what the code above really is saying.
- Create a new type, Name.
- Name has a single constructor that takes a string.
- Name has a member variable, fName, whose value can change at runtime.
- Name has a public property, FName, that has a getter and a setter.
OK, so now what does this look like in C#? I add the F# library to a C# project, instantiate a copy of Stuff.Name (I’ll get to the Stuff item in a moment), and then I right click on Stuff.Name and pick Go to Definition. Since we are in C# land, VS 2008 will pull up the C# vision. This looks exactly like the following:
using System;
public static class Stuff
{
[Serializable]
public class Name
{
public Name(string fname);
public string FName { get; set; }
}
}
That’s kind of weird. I didn’t expect to see Name declared as a inner class from a static class whose name comes from the name of the F# file. Still, that’s what we have. Does this mean that F# code doesn’t allow one to create CLR namespaces? No– of course not! So, how do you get the Name class into a CLR namespace called SomeNamespace? I did a little digging and found out how:
namespace SomeNamespace
type Name(fname : string) =
let mutable fName = fname
member this.FName with get() = fName
and set(x) = fName <- x
Yeah– there’s a keyword called namespace that allows you to add objects to a CLR namespace. The odd bit here is that one doesn’t say namespace blah =. Instead, you omit the ‘=’. The ‘=’ will work, but you will get a message saying that the syntax has been deprecated. With this small change in place, things look more correct to my C# eyes. The static class disappears, and that’s good!
using System;
namespace SomeNamespace
{
[Serializable]
public class Name
{
public Name(string fname);
public string FName { get; set; }
}
}
Right now, I think my focus will be on writing F# code that plays well/looks natural to C# developers. I’ll keep that point of view until I see a reason to change.