gpt4 book ai didi

c# - 我应该 null 保护我的 F# 代码免受 C# 调用吗

转载 作者:太空狗 更新时间:2023-10-30 00:37:50 26 4
gpt4 key购买 nike

我正在用 F# 编写一个库,其中包含一些公开可见的接口(interface)和基类。通常,我避免指定 [<AllowNullLiteral>]在我的自定义类型上,因为这会使我的 F# 代码中的验证逻辑复杂化(请参阅 this nice post for goods and bads of null handing in F# to get a picture ),而且 F# 最初不允许 null对于 F# 类型。因此,我仅针对接受 null 的类型验证空值值有效。

但是,当我的库用于其他 .NET 语言(例如 C#)时,会出现问题。更具体地说,我担心在 C# 代码调用时我应该如何实现接受 F# 声明的接口(interface)的方法。接口(interface)类型在 C# 中可以为 null,我怀疑 C# 代码传递 null 不会有问题。到我的 F# 方法。

我担心调用者会因 NPE 而崩溃和燃烧,问题是我什至不允许在 F# 代码中正确处理它——比如抛出 ArgumentNullException -- 因为相应的接口(interface)缺少 AllowNullLiteral属性。我担心我必须使用该属性并在我的 F# 代码中添加相关的空值检查逻辑才能最终防止此类灾难。

我的担心合理吗?我有点困惑,因为我最初尝试坚持良好的 F# 实践并避免 null越多越好。如果我的目标之一是允许 C# 代码子类化并实现我在 F# 中创建的接口(interface),这会发生什么变化?如果来 self 的 F# 代码的所有非值类型是公共(public)的并且可以从任何 CLR 语言访问,我是否必须允许它们为空值?是否有最佳实践或好的建议可供遵循?

最佳答案

您可以采用两种基本方法:

  1. 在您的 API 设计中记录不允许将 null 传递给您的库,并且调用代码负责确保您的库永远不会收到 null。然后忽略该问题,当您的代码抛出 NullReferenceException 并且用户提示它时,将他们指向文档。

  2. 假设您的图书馆从“外部”收到的输入不可信,并在您图书馆的“面向外部”的边缘放置一个验证层。该验证层将负责检查 null 并抛出 ArgumentNullException。 (并指向在异常消息中显示“不允许空值”的文档)。

正如您可能猜到的那样,我更喜欢方法 #2,尽管它需要更多时间。但是您通常可以创建一个随处使用的函数来为您完成此操作:

let nullArg name message =
raise new System.ArgumentNullException(name, message)

let guardAgainstNull value name =
if isNull value then nullArg name "Nulls not allowed in Foo library functions"

let libraryFunc a b c =
guardAgainstNull a nameof(a)
guardAgainstNull b nameof(b)
guardAgainstNull c nameof(c)
// Do your function's work here

或者,如果您有一个更复杂的数据结构,您必须检查内部空值,然后将其视为 HTML 表单中的验证问题。您的验证函数要么抛出异常,要么返回有效的数据结构。所以你的库的其余部分可以完全忽略空值,并以一种漂亮、简单、惯用的 F# 方式编写。并且您的验证函数可以处理您的域函数和不受信任的“外部世界”之间的接口(interface),就像您处理 HTML 表单中的用户输入一样。

更新:另请参阅 https://fsharpforfunandprofit.com/posts/the-option-type/ 底部附近给出的建议(在“F# 和 null”部分),Scott Wlaschin 写道,“作为一般规则,null 永远不会在“纯”F# 中创建,而只能通过与 .NET 库或其他外部系统交互来创建。[... ] 在这些情况下,最好立即检查空值并将它们转换为选项类型!”您的库代码希望从其他 .NET 库获取数据,情况类似。如果您想允许空值,您可以将它们转换为 Option 类型的 None 值。如果您想禁止它们并在传递 null 时抛出 ArgumentNullException,您也可以在库的边界处执行此操作。

关于c# - 我应该 null 保护我的 F# 代码免受 C# 调用吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44240421/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com