【问题标题】:Nothing equals String.Empty, null does not equal String.Empty, what am I missing here?没有什么等于 String.Empty,null 不等于 String.Empty,我在这里缺少什么?
【发布时间】:2011-03-09 01:13:11
【问题描述】:

在一个混合代码项目(VB 和 C#)中,我们正在调试一些旧的 Visual Basic 代码,如下所示:

If Request.Params("xxx") <> "" Then
   'do something

我认为这是一个错误,因为 Request.Params 可能是 null,在这种情况下,该语句将变为错误,这不是我们的想法。

所以我想。我刚刚发现——又一次——VB 的Nothing 和C# 的null 不是一回事,Nothingnull 不同。事实上:

if(String.Empty == null)          // in C# this is always false (correct)
If String.Empty = Nothing Then    ' in VB this is always true (????)

这怎么可能?这是向后兼容性问题吗?

【问题讨论】:

    标签: c# .net vb.net vb.net-to-c#


    【解决方案1】:

    Nothing 在 VB 中对字符串有特殊的含义。要测试一个字符串引用是否为空,你需要:

    If value Is Nothing
    

    来自VB comparison operators documentation

    数值比较将 Nothing 视为 0.字符串比较将Nothing视为“”(空字符串)。

    我怀疑这只是为了向后兼容 VB6 - 如果我是 VB 开发人员,我不会对此感到满意。

    表格对比

    If value = Nothing
    

    编译为对Microsoft.VisualBasic.CompilerServices.Operators.CompareString 的调用,如果一个操作数为空而另一个操作数为空,则返回 0(即相等)。

    【讨论】:

    • 是的,谢谢,我明白了:)。但你答案的第一部分很有趣。与 Nothing 相比时,Equals 应该给出一个引用,不是吗?
    • 啊,忽略我之前的评论。你同时编辑。比较喜欢,谢谢参考。我也不太满意。关于“为什么”部分的任何(更多)想法?听起来很像 Perl:一切都是字符串,直到另行通知。
    • @Abel:现在改变行为为时已晚。他们本可以在 VB6 / VB7 点做到这一点,但决定不这样做。他们试图在许多可能的地方保持兼容性。据我所知,他们现在并不特别希望人们使用 VB6。
    • @Abel - 对于 .NET 4.0,他们在功能访问方面使事情更接近,而不是使两种语言相同但拼写不同 - 如果他们这样做了,为什么要有两种语言?但是在 VB.Net 中没有什么是奇怪而神奇的野兽 - 在通用代码中,它有时更接近默认值(T)
    • @Damian:这是一个很好的比较,谢谢! @Jon:感谢您的更新,我赞同您的意见 :)
    【解决方案2】:

    在 vb6 中,字符串变量的默认值为空字符串。依赖这种行为的 vb6 程序员不会比依赖 int 变量的默认零初始化的 C 程序员“更糟”;这两种行为都被指定为语言的一部分。

    此外,在 COM(以前版本的 VB6 所基于的框架)中,每当创建对字符串的引用时,都必须手动处理它。由于最常用的字符串是空字符串,因此许多 COM 方法被明确记录为将空指针等同于空字符串。这意味着一个函数返回一个空字符串或传递一个作为值参数或返回一个可以简单地传递一个空指针而无需分配任何东西;空指针的接收者将不必取消分配任何东西。

    由于 .net 中的对象不需要显式解除分配,因此将空引用视为空字符串的性能优势不再适用。尽管如此,从代码调用的方法可能预期行为类似于 COM 方法的行为,通常会将空字符串引用视为与空字符串相同。

    【讨论】:

    • 有趣的考虑和想法,尤其是。与 COM 的比较。感谢您将其添加到这个相当老的问题 +1 ;)
    【解决方案3】:

    你想要的

    If Not String.IsNullOrEmpty(Request.Params("xxx") Then
        ...
    End If
    

    或者

    if (!String.IsNullOrEmpty(Request.Params("xxx")) {
        ...
    }
    

    【讨论】:

    • 是的,很可能。但这不是这里的问题......问题是为什么在 VB 中感知的(不)平等不是实际的(不)平等。为什么Nothing 不是null,而通常是。
    • 是的,只是误读了,这仍然有助于避免这个问题。 VB.NET 中的 = 与 Jon Skeet 澄清的 == 不同(应该被接受)。
    • 我认为重点是在 BASIC 中,字符串不是指针,它只是零个或多个字符。因此无法与 NULL 进行比较。
    • 即使在 BASIC 中,字符串也是一个指针,但它被语言隐藏了。这是 VB.NET,而不是 BASIC。指针在 .NET 中已经接近消失(对于一些不安全的代码来说是安全的)并且已经被引用所取代。 .NET 的任何语言都绑定到 CLR 规范,这意味着字符串是被特殊处理的引用类型(即:只读)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2012-03-27
    相关资源
    最近更新 更多