我有一些强制数值范围的类型,我在单个项目中的许多文件中使用它们。它们看起来像这样:
[<Struct>]
type NonNegativeMoney =
new(x) =
if x < 0m then invalidArg "x" "Ruh-roh..."
{ Value = x }
val Value : decimal
static member (+) (x: NonNegativeMoney, y: NonNegativeMoney) = NonNegativeMoney(x.Value + y.Value)
我现在希望将这些类型改为内部类型,并仅保留我的OO类型模型为公共类型。然而,当我将这些类型转换为内部类型时,会出现以下编译器错误:
这个问题已经在问题“为什么F#编译器会因此中缀运算符而失败?”中得到了解决。回答中提出的解决方案是使用F#签名文件将这些类型变为内部类型。这在该问题中的类型仅限于同一文件中使用操作符的情况下可以解决。但是,我似乎找不到一种使其在项目中所有文件中都可以访问的方法。如果我使用签名文件,则在文件内有效,但在文件间无效。成员或对象构造函数 'op_Addition' 不是公共的。私有成员只能从声明类型内访问。受保护成员只能从扩展类型访问,不能从内部 lambda 表达式访问。
有没有办法使这些类型成为程序集内部类型,但在项目的所有文件中都可见?我想保留这些操作符,因为我正在使用像
Seq.sum
等库函数需要这些操作符的类型进行求和。
InternalsVisibleTo
属性进行注释吗? - s952163InternalsVisibleTo
是用于跨程序集使用的。我正在尝试在同一程序集中使用运算符。请您详细说明一下? - bentayloruk[<assembly: InternalsVisibleTo("NonNegativeMoney")>]
,您可以尝试一下,但正如您所说,您的用例略有不同。 - s952163InternalsVisibleTo
属性在构造函数中需要一个程序集名称,因此我不能使用NonNegativeMoney
。也许我可以将数字类型提取到一个新的程序集中,使用签名文件使其成为内部元素(如其他答案所述),然后添加InternalsVisibileTo
属性,并引用我的主程序集。但这种方法感觉很不好。希望有更好的解决方案。 - bentaylorukInternalsVisibleTo
,但现在我得到了BlahBlahType.fs(10, 10): [FS0001] The member or object constructor 'op_Addition' is not public. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.
我可以创建该类型的值(所以我知道IVT正在工作),但是操作使用仍然失败。 - bentayloruk