2

.NET 库具有String.IsNullOrEmpty(value As String).

我可以<stringValue>.IsNullOrEmpty()通过简单的扩展方法创建更舒适:

<Extension>
Function IsNullOrEmpty(s As String) As Boolean
    Return String.IsNullOrEmpty(s)
End Function

我的第一个快速理解是,这不是开箱即用的,因为它可以NullReferenceExceptionnull. 直到我发现这是不正确的,因为Nothing在 String 中变量被键入为字符串。

Dim s As String = Nothing
If s.IsNullOrEmpty() Then ... 'this will always return true, no exception thrown

使用默认表单String.IsNullOrEmpty(s)而不是s.IsNullOrEmpty()我缺少的表单是否有意义?

当然,在即时窗口中我不能输入

? Nothing.IsNullOrEmpty()

但无论如何这都是无稽之谈。这正常工作:

? CStr(Nothing).IsNullOrEmpty()
4

3 回答 3

4

之所以默认是 String 中的静态方法而不是普通方法,是因为在 Nothing/null 上调用方法会导致异常。因此,您必须先检查 Nothing/null,然后再调用另一个方法来检查它是否可能是 Nothing/null 是没有意义的。

你的扩展方法之所以不会导致这种情况是因为它是一个获取对象作为参数的方法,就像String中的静态方法一样。

但是,如果您的意思是为什么没有完成扩展方法,那么 Damien_The_Unbeliever 的回答是正确的:一开始就没有扩展方法。并且在以后创建一个副本可能毫无意义。

于 2015-08-15T10:48:53.633 回答
3

它没有作为扩展方法实现(归根结底,它仍然只是一个静态方法)的原因是历史性的 - 扩展方法直到 C# 3 / VB 9 才存在 - 五年多之后String.IsNullOrEmpty在 .NET 1.0 中首次亮相。

NullReferenceException当他们的第一个参数是时不抛出的扩展方法null实际上是非常令人困惑的推理 - 因为这给了他们与普通实例方法不同的行为。

当异常被手动抛出,抛出而不是作为ArgumentNullException,或者只是从实现的深处传播(与NullReferenceException在调用站点抛出的普通实例方法不同)时,它们已经足够令人困惑了。

于 2015-08-15T11:01:00.740 回答
1

毕竟,添加我自己的答案“For Dummies”,也许它可以帮助某人:

标准类方法不能在 null 上调用,即使该 null 是字符串 ( CStr(Nothing))。因此,如果 if为空,那么简单地拥有stringValue.IsNullOrEmpty()不会作为标准方法工作。stringValue

它仅适用于扩展方法,因为它是实际接受对象作为其第一个参数的静态方法。那里有 null 没问题。但这会令人困惑,因为由于标准方法的行为,没有人会期望在空对象上调用方法——这并不常见,它看起来很像未修复的错误,尽管它不是。这种混淆迫在眉睫,尤其是在 IDE 之外读取源代码时——扩展方法无法与标准方法明确区分开来。

因此,我们可以完全放弃使用可以在 null 上调用的扩展方法,或者在名称上明确区分扩展方法。后一种做法还可以帮助加入项目的其他人提高对任何与项目相关的扩展方法的认识:“标准类有附加的东西”。这种做法还可以防止在发现时混淆,stringValue.IsNull()这通常是无稽之谈。有很多方法可以写出独特的名字,但我认为最好的方法是添加独特的字符,这样名字可以保持简短,不受其他单词的影响。

这是我的想法:在美国以外,我们更习惯于非 ASCII 字符,有一些像这样的有趣字母表。它们的独特字符之一可以适合作为字形添加到名称中,从而创建例如stringValue.IsNullOrEmptyᛎ()也对应于扩展方法的常用徽章图形的示例。

于 2015-08-15T11:33:08.140 回答