In C#, I can compile
static class Foo<T> { /* static members that use T */ }
The result is generic and is not instantiable.
What is the equivalent F# code? module<'a>
doesn't compile, and type Foo<'a>
is instantiable.
In C#, I can compile
static class Foo<T> { /* static members that use T */ }
The result is generic and is not instantiable.
What is the equivalent F# code? module<'a>
doesn't compile, and type Foo<'a>
is instantiable.
I thought at first that this would be close to what you wanted:
type Foo<'a> private() =
static member Blah (a:'a) =
printfn "%A" a
Being like the idiom pre c# 2.0 of being instantiable only via reflection or by the class itself (which hopefully wouldn't do it).
however this is compiled down to:
[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)]
public class Foo<a>
{
internal Foo() {...}
public static void Blah(a a) {...}
}
Which implies that other classes within the f# assembly could instantiate it.
However the ever informed Brian has indicated that the f# compiler respects this private setting despite the underlying CLR type which means that the only way to instantiate would be via reflection or by using something like the InternalsVisibleTo attribute.
This may still be acceptable for your needs...
The other answers so far each have part of the picture...
type Foo<'a> private() = // '
static member Blah (a:'a) = // '
printfn "%A" a
is great. Disregard what Reflector generates, you cannot instantiate this class from within the F# assembly (since the constructor is private), so this works well.
F# does allow static constructors as well, the syntax is to include 'static let' and 'static do' statements in the class (which work analogously to how 'let' and 'do' work as part of the primary constructor body for instances). A full example:
type Foo<'a> private() = // '
static let x = 0
static do printfn "Static constructor: %d" x
static member Blah (a:'a) = // '
printfn "%A" a
//let r = new Foo<int>() // illegal
printfn "Here we go!"
Foo<int>.Blah 42
Foo<string>.Blah "hi"