0

这是一个非常奇怪的问题,你可能会发现它是。我正在做一个巨大的 VB6 到 VB.NET 2010 的迁移项目。作为 VB6 的一部分,我们有一个常量定义为 NullString = "" 在 .NET 中,它也在类似的行上迁移并使用。我们遇到的问题是,当将 RecordSet 中的值(它只是 DataTable 的包装器)与这个 NullString 进行比较时,我们会得到比较错误。由于该项目正在积极开发中,我们必须依赖迁移工具(VB MIgration Partner),它了解很少的 Pragma 但不太先进。我创建了一个类(NullStringClass)并重载了“=”和“<>”运算符,它对我的​​比较问题进行了排序。但是在某些地方,我们有 someVar = NullString,其中 someVar 是一个字符串变量。现在,我收到无法从 NullStringClass 转换为字符串的错误。

<System.Reflection.DefaultMember("Value")> _
Public Class NullStringClass

属性定义为:

Public Property Value() As String
    Get
        Return ""
    End Get
    Set(ByVal value As String)

    End Set
End Property

但它仍然抛出异常。据我所知,这应该解决了我的问题,但没有运气。我仍然得到同样的错误。所以,我的问题是一样的。有什么方法可以将该 NullString 变量转换为一个类并使用运算符重载进行不同的比较(包括 Null 和 Nothing),还可以用作对字符串变量的正常赋值?例如意味着

Dim s as String
s = NullString

应该工作以及以下应该工作:

If rsData("MyField").Value <> NullString Then
'Note: rsData("MyField").Value is DbNull

这是运算符重载的示例(如果有人感兴趣)

Public Shared Operator <>(ByVal mmyVal As Object, ByVal objVal As NullStringClass) As Boolean
    If TypeOf mmyVal Is String Then
        Return (Not String.IsNullOrEmpty(mmyVal))
    Else 'If TypeOf mmyVal Is Object Then
        Return (Not IsDBNull(mmyVal))
    End If
End Operator

谢谢,尼克

4

2 回答 2

1

I had put this question after struggling for 2 days and scratching my head for making that "=" work. (Operator Overloading was working fine within 1 hr). The solution to get "s = NullString" right was to put implicit operator for my NullStringClass.

Public Shared Widening Operator CType(ByVal obj As String) As NullStringClass
    Return New NullStringClass()
End Operator

Public Shared Narrowing Operator CType(ByVal obj As NullStringClass) As String
    Return String.Empty
End Operator

Although only Narrowing Operator was enough, I had put Widening as well (will be removed in production code as its not required). Hope this is helpful for someone like me :-)

于 2012-07-12T08:17:47.423 回答
1

在 vb.net 中,string保存null或未初始化值的类型的存储位置在语义上与空字符串不同。如果您希望将这样的存储位置与另一个已知不为空的字符串进行比较,并且如果存储位置为空(而不是抛出异常),则此类比较仅返回 false,您可以将表达式编写为"Whatever".Equals(storageLocation). 如果您希望比较两个字符串,其中一个或两个可能为空,并且空字符串比较彼此相等但不与其他任何字符串(包括空字符串)比较,您可以使用String.Equals(string1, string2). 如果你想确定一个字符串是空还是空,你可以使用String.IsNullorEmpty(theString). 如果您希望以将空字符串视为空的方式执行比较,您可以编写自己的静态比较,以这种方式执行比较,或者您可以编写一个函数,给定 a string,返回传递的-in 字符串,如果非空,否则返回String.Empty

希望以上之一是您所追求的。请注意,它们与 VB6 所谓的“默认属性”无关,但您的问题似乎并不是在询问 VB6 属性(Let以及Set.

附录

如果您想要一个大多数情况下可以像普通字符串一样使用的字符串类型,但默认为空字符串而不是Nothing,您可以使用这样的东西(不完整,但应该是一个好的开始)

Public Structure SafeString
    Implements IComparable(Of SafeString), IEquatable(Of SafeString)

    Dim _St As String

    Sub New(St As String)
        _St = St
    End Sub

    Public Overrides Function ToString() As String
        Return If(_St, "")
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return If(_St, "").GetHashCode()
    End Function

    Public Overrides Function Equals(obj As Object) As Boolean
        If obj Is Nothing OrElse Not (TypeOf (obj) Is SafeString) Then Return False
        Return If(_St, "") = If(CType(obj, SafeString)._St, "")
    End Function

    Public Function CompareTo(other As SafeString) As Integer Implements System.IComparable(Of SafeString).CompareTo
        Return If(_St, "").CompareTo(If(other._St, ""))
    End Function

    Public Overloads Function Equals(other As SafeString) As Boolean Implements System.IEquatable(Of SafeString).Equals
        Return If(_St, "") = If(other._St, "")
    End Function

    Public Shared Widening Operator CType(st As String) As SafeString
        Dim ret As New SafeString
        ret._St = st
        Return ret
    End Operator

    Public Shared Widening Operator CType(safeSt As SafeString) As String
        Return If(safeSt._St, "")
    End Operator

    Function Length() As Integer
        Return If(_St, "").Length()
    End Function
    Function SubString(startIndex As Integer) As String
        Return If(_St, "").Substring(startIndex, Length)
    End Function
    Function SubString(startIndex As Integer, length As Integer) As String
        Return If(_St, "").Substring(startIndex, length)
    End Function

您会注意到一个非常常见的模式If(_St, "")。该函数将使用 _St 如果它不为空,或者如果它是空字符串。它不支持所有方法String,但是如果您需要任何尚不工作的方法,您应该能够遵循 等显示的模式。 和 之间的分配和Length比较应该按预期工作,但不会将任何视为等于任何(无法更改覆盖的行为以使字符串与任何其他类型的对象进行比较;如果要比较为假,则必须这样做。StringSafeStringObject.EqualsStringSafeStringString"Test".Equals(New SafeString("Test"))(New SafeString("Test")).Equals("Test")

于 2012-07-12T15:28:31.353 回答