【问题标题】:How to define a public static readonly field?如何定义公共静态只读字段?
【发布时间】:2017-05-02 21:25:06
【问题描述】:

在 C# 中,可以像这样定义一个公共静态只读字段:

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

在F#中,我能想到的最符合上述定义的代码是:

namespace MyNamespace

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

但这实际上转换为以下 C# sn-p:

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

如何在 F# 中定义公共静态只读字段? const 不适合我,因为我想work with different assemblies

【问题讨论】:

  • 为什么不直接编写 C# 代码并在 F# 中使用编译后的代码,例如 stackoverflow.com/questions/3901805/…
  • 为什么特别需要只读字段?为什么你不能直接删除 Literal 属性并在那里有一个正常的 let-bound 值(它编译为一个 getter-only 属性)?
  • 两个选项(使用 C#,删除 Literal 属性)都是完全可行的,我只是想知道我是否遗漏了一些允许我直接在 F# 中执行此操作的内容。

标签: .net f#


【解决方案1】:

只需删除 Literal 属性并使用 let-bound 值:

module MyClass =
    let MyValue = "Test"

这将编译为静态 getter-only 属性(ILSpy 生成的 C#)的等效项:

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

如果该值涉及计算(而不是像您的情况那样是文字),它实际上将绑定为模块底层内部类中的静态只读字段(并在 getter 主体中引用)。如果愿意,您可以使用 ILSpy 验证自己。

如果您对编译器生成的实际 IL 感兴趣 - F# 作为一种语言没有单独的只读字段概念(因为 let-bound 值、记录字段等是只读的默认)。它甚至不保留关键字。

【讨论】:

    【解决方案2】:

    你可以在下一个例子中使用一个公共常量,你可以使用

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

    这对所有其他类都是可见的,并且会更简单

    【讨论】:

    • 作者要求的是 F#,而不是 C#。
    猜你喜欢
    • 2011-03-24
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    相关资源
    最近更新 更多