【问题标题】:How to make CStr() working on boxed custom data type?如何使 CStr() 处理盒装自定义数据类型?
【发布时间】:2016-03-24 18:28:49
【问题描述】:

我可以在盒装内置 类型上成功使用CStr()。但是我怎样才能用盒装的自定义类型实现同样的效果呢?我来了

Exception thrown:  'System.InvalidCastException' in Microsoft.VisualBasic.dll

密码:

' sample custom type
Structure Record
    Public Property Value As Integer
    Overloads Function TOSTRING() As String  ' capitalizaition intentional to reveal usage 
        Return ">>" & Value.ToString() & "<<"
    End Function
    Shared Operator &(left As String, right As Record) As String
        Return left & right.TOSTRING()
    End Operator
    Shared Widening Operator CType(left As Record) As String
        Return left.TOSTRING()
    End Operator
End Structure

' both use cases
Sub Main()
    ' demo with built-in type
    Dim i As Integer = 3
    Dim ib As Object = i ' boxed into Object
    Debug.Print("i:" & CStr(i))
    Debug.Print("ib:" & CStr(ib)) ' works OK

    ' demo with custom type
    Dim r As New Record With {.Value = 3}
    Dim rb As Object = r ' boxed into Object
    Debug.Print("r:" & CStr(r))
    Debug.Print("rb:" & CStr(rb)) ' Exception thrown: 
                                  ' 'System.InvalidCastException' in Microsoft.VisualBasic.dll
End Sub

【问题讨论】:

  • 改用.ToString()
  • @RezaAghaei - 不会无缝处理空值。相反,我想让我的类型在运行时看起来“原生”。也许我只是错过了一些明显的东西。
  • 如果您不想处理空值,请使用Convert.ToString(rb)
  • @RezaAghaei – Convert.ToString(rb) 打印 rb:Application1.Module1+Record,而不是预期的 &gt;&gt;3&lt;&lt;
  • 我使用了Public Overrides Function ToString() As String,它显示了预期的结果。

标签: vb.net .net vb.net struct tostring boxing


【解决方案1】:

您可以通过这种方式覆盖ToString

Public Overrides Function ToString() As String
    'Put the logic here
    Return ">>" & Value.ToString() & "<<"
End

然后使用Convert.ToString()方法将对象转换为字符串。

例子:

Dim r As New Record With {.Value = 3}
Dim rb As Object = r ' boxed into Object
MessageBox.Show("rb:" & Convert.ToString(rb)) 'Shows >>3<<

【讨论】:

  • 是的,技术上是正确的。但是自定义数据类型永远不会像原生类型那样与 CStr() 一起使用吗?
  • 很遗憾,在VB6 之后我还没有与CStr 合作过,我一直使用.Net 方式ToString 方式。
  • 好的,我接受这个答案。如果有人发现如何使CStr(rb) 工作,也许我会在将来标记另一个。
  • 您也可以使用CStr(DirectCast(rb, Record))。如果你喜欢
  • 是的,但这需要Case 声明预期的数据类型。我想知道,为什么vb.netCStr() 中无缝处理自己的盒装类型?它是否也在内部使用Case? (Int32UInt32FloatDouble,...)。这可以解释...
【解决方案2】:

最好的方法是覆盖用户类型中的.ToString。我相信Cstr()CBool() 和更多的东西仍然存在以实现向后兼容性。 (VB6)

在您的类型中覆盖.ToString 的另一个好处是,在调试中,当您观察到您的类型的引用变量时,您可以获得对象的更有意义的信息,而不仅仅是对象的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    相关资源
    最近更新 更多