【问题标题】:What is the equivalent of C#'s `default` in VB.NET?VB.NET 中 C# 的 `default` 的等价物是什么?
【发布时间】:2011-01-20 17:00:56
【问题描述】:

我通常在家中使用 C#,我正在查看一些 VB.NET 代码中的性能问题——我希望能够将某些内容与某个类型的默认值进行比较(有点像 C# 的 @ 987654322@关键字)。

public class GenericThing<T1, T2>
{
    public T1 Foo( T2 id )
    {
        if( id != default(T2) ) // There doesn't appear to be an equivalent in VB.NET for this(?)
        {
            // ...
        }
    }
}

我被引导相信 Nothing 在语义上是相同的,但如果我这样做:

Public Class GenericThing(Of T1, T2)
    Public Function Foo( id As T2 ) As T1
        If id IsNot Nothing Then
            ' ...
        End If
    End Function
End Class

那么当T2Integerid的值为0时,条件依然成立,if的主体被求值。但是,如果我这样做:

    Public Function Bar( id As Integer ) As T1
        If id <> Nothing Then
            ' ...
        End If
    End Function

那么条件不满足,body不求值...

【问题讨论】:

  • 可能重复 [VB 等效于 C# 的默认值 (T)](stackoverflow.com/questions/833791/…)
  • @decyclone 这个问题不包括一般情况;事实上,在我的问题中,我表明我知道在大多数情况下使用Nothing...
  • 如果 id.Equals(CType(Nothing, T2)) 那么

标签: .net vb.net generics


【解决方案1】:

与 C# 不同,VB.NET 不需要用表达式初始化局部变量。它由运行时初始化为其默认值。正是您需要替换 default 关键字:

    Dim def As T2    '' Get the default value for T2
    If id.Equals(def) Then
       '' etc...
    End If

不要忘记评论,它会让人觉得“嗯?”一年后。

【讨论】:

    【解决方案2】:

    这不是一个完整的解决方案,因为您的原始 C# 代码无法编译。您可以通过局部变量使用 Nothing:

    Public Class GenericThing(Of T)
        Public Sub Foo(id As T)
            Dim defaultValue As T = Nothing
            If id <> defaultValue Then
                Console.WriteLine("Not default")
            Else
                Console.WriteLine("Default")
            End If
        End Function
    End Class
    

    这不能编译,就像 C# 版本不能编译一样 - 你不能像这样比较不受约束的类型参数的值。

    你可以使用EqualityComparer(Of T) - 然后你甚至不需要局部变量:

    If Not EqualityComparer(Of T).Default.Equals(id, Nothing) Then
    

    【讨论】:

    • 我认为我从示例中提取了太多特定于业务的术语,但 似乎 适用于值类型 - 你知道它作为参考的效果如何类型也一样?
    • @Rowland:据我所知应该没问题。
    • 嗯,它在我输入的同时编译,所以我很快就会知道;我可以看到这将如何迫使编译器发挥作用并使其工作
    【解决方案3】:

    代码中的问题是 IsNot 运算符,而不是 Nothing 关键字。来自docs

    IsNot 运算符确定两个对象引用是否引用不同的对象。但是,它不执行值比较。

    您正在尝试与引用运算符进行值比较。一旦您意识到这一点,Jon Skeet 或 Hans Passant 的答案就会成为显而易见的解决方案。

    【讨论】:

    • 说得通——总是让我恼火的是,VB 同时有=Is 用于比较,开发人员需要知道是分别比较值类型还是引用类型。
    • @Rowland - C# 也有一个“is”运算符。我使用适用于 C# 和 VB 的经验法则:首先使用 .Equals(),如果编译器抱怨使用 == / =,如果编译器仍然抱怨使用 is。
    • @Joel/Rowland,习惯让我喜欢 =/== 与对象/类。我倾向于在使用可空类型(Guid?、DateTime?等)时使用 Equals。我遇到了很多不正确地处理 Guid(作为字符串)而不是 Guid 的代码? ...实际上,当我必须使用 is null 时,它在 SQL 中更让我恼火,其中 = null 通常会使我正在尝试做的事情失败。
    猜你喜欢
    • 1970-01-01
    • 2015-06-04
    • 2011-05-23
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多