5

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.

Community
  • 1
  • 1
Michael Szvetits
  • 364
  • 1
  • 2
  • 11
  • Why not just write the C# code and use the compiled code in your F# a la http://stackoverflow.com/questions/3901805/how-to-use-c-sharp-object-from-f? – Heretic Monkey May 02 '17 at 21:33
  • 2
    Why do you specifically need a read-only field? Why can't you just drop `Literal` attribute and have a normal let-bound value there (which compiles to a getter-only property)? – scrwtp May 02 '17 at 21:36
  • Both options (use C#, drop Literal attribute) are completely viable, I was just wondering if I am missing something that allows me to do this directly in F#. – Michael Szvetits May 02 '17 at 21:49

2 Answers2

3

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.

scrwtp
  • 13,437
  • 2
  • 26
  • 30
-1

you just might use a public constant in the next example you can use

public class Constants
{
    public const string CONSTANT_VALUE = "MY CONSTANT";
}

this will be visible for all other classes and it will be simpler