How do I set a read-only static public field?

advertisements

In C#, one can define a public static readonly field like this:

namespace MyNamespace
{
    public static class MyClass
    {
        public static readonly string MyValue = "Test";
    }
}

In F#, the code I can think of which matches the definition above best is:

namespace MyNamespace

module MyClass =
    [<Literal>]
    let MyValue = "Test"

But this actually translates to the following C# snippet:

namespace MyNamespace
{
    public static class MyClass
    {
        public const string MyValue = "Test";
    }
}

How can I define a public static readonly field in F#? const is not an option for me since I want to work with different assemblies.


Just drop the Literal attribute and use a let-bound value:

module MyClass =
    let MyValue = "Test"

This will compile as an equivalent of a static getter-only property (ILSpy-generated C#):

public static string MyValue
{
    [DebuggerNonUserCode, CompilerGenerated]
    get
    {
        return "Test";
    }
}

If the value involves a computation (rather than being a literal as in your case), it will actually be bound as a static readonly field in the internal class underlying the module (and referred to in the getter body). You can verify that yourself with ILSpy if you like.

That's if you're interested in actual IL generated by the compiler - F# as a language doesn't have a separate notion of a read-only field (as let-bound values, record fields etc. are read-only by default). It doesn't even reserve the keyword.