导出到其他 .NET 语言时,何时在 F# 中使用驼峰命名法?

When will I use camelCase in F# when exporting to other .NET languages?

基于The F# Component Design Guidelines,F# 应使用PascalCase 以符合.NET Framework 命名约定。

假设我正在使用 C# 或 VB.NET 并且想要导入 F# 库,我应该什么时候期望 camelCase 约定出现在该库中?

看看FsCheck library, and specifically its Gen module。 (FsCheck 源代码中还有其他示例,但这个示例很容易阅读)。 FsCheck 旨在从 F# 和 C# 中使用,Gen 模块的设计反映了:

module Gen =
    // ...

    [<CompiledName("Map"); EditorBrowsable(EditorBrowsableState.Never)>]
    let map f (gen:Gen<_>) = gen.Map f

    [<CompiledName("Sized"); EditorBrowsable(EditorBrowsableState.Never)>]
    let sized fgen = Gen (fun n r -> let (Gen m) = fgen n in m n r)

    [<CompiledName("Sized"); CompilerMessage("This method is not intended for use from F#.", 10001, IsHidden=true, IsError=false)>]
    let sizedFunc (sizedGen : Func<int,Gen<_>>) =
        sized sizedGen.Invoke

暂时忽略这些函数的实现,看看它们的名字,以及各自赋予的CompiledName属性。当您从 F# 调用 map 函数时,您将调用它作为 Gen.map,但是当您从 C# 使用它时,CompiledName 属性将使您看到它的名称为 Gen.Map。与 sized 函数类似,从 F# 代码调用时将调用 Gen.sized,从 C# 调用时将以名称 Gen.Sized 显示。另请注意第二个函数如何具有相同的 CompiledName(从 C# 看),但 F# 代码在 Gen.sizedGen.sizedFunc 之间有区别(并且 F# 编译器也会警告您如果您尝试使用 Gen.sizedFunc 那 "This method is not intended for use from F#"),因为该重载需要 C# 代码使用的函数类型,并且纯粹是为了方便 C# 编码人员使用该库。 (F# 函数使用 FSharpFunc 类型,在某些情况下其行为不同于 C# Func 类型)。

然而,您的问题并没有那么多"How should I write my F# library so that it can be used by C# coders?"。相反,您的问题是,"As a C# coder, what should I expect from F# libraries in terms of naming conventions?"那个问题的答案是:这取决于您使用的库。

正如您所指出的,F# 组件设计指南建议将 PascalCase 名称用于设计用于调用代码的函数。 FsCheck 是一个很好的图书馆例子。但并不是所有的库都是为了便于从 C# 使用而编写的。有些库在编写时仅考虑使用它们的其他 F# 代码,这些库不一定 符合设计指南,因为 F# 约定是对函数名称使用驼峰式命名。

所以虽然这不是一个完全令人满意的答案,但它是我能给你的最好的答案,因为我不知道你将使用哪些库。