哪个更有效的Cstr(value)或value.ToString()

问题描述 投票:10回答:9

我想知道使用CStr()或object.toString()效率更高。我之所以这样问,是因为尽管我完成的所有CStr()操作都是在要处理的对象上调用.ToString()方法。

但是最近在使用没有任何类型约束的通用方法时,我不得不使用object.ToString()而不是CStr(object),以下仅是一个示例来说明问题。

Public Function IDFromObject(Of ID_TYPE)(ByVal value As ID_TYPE) As String
    Return value.ToString
End Function

按预期编译,但以下未使用CStr()。它给出了ID_TYPE类型的编译错误值,无法转换为字符串。但显然可以使用.ToString()

Public Function IDFromObject(Of ID_TYPE)(ByVal value As ID_TYPE) As String
    Return CStr(value)
End Function
vb.net casting
9个回答
12
投票

here起(再好不过了:):

CStr是关键字,而ToString是功能(方法)。 CStr编译内联,它创建代码取决于关于传递对象的类型。它的主要是那里的人习惯它来自以前的VB版本。一世不再在.Net中使用CStr(因为它的作用不明显在那种情况下有据可查)。

差异取决于您使用的ToString函数。每种类型可以有自己的实现。


8
投票

出于可读性考虑,如果我需要用VB.NET编写代码(我是C#程序员),我将尽可能避免使用VB特定的关键字/函数。仅通过使用.NET类和方法,使用其他.NET语言进行开发的人员将可以更轻松地理解您的代码。更不用说这些功能主要是为了与VB6兼容,并且与.NET处事方式相比,它们看起来有些不合适。

当然可能会有合理的例外,有时VB.NET确实使执行某些任务非常容易,并且可以很方便地利用此功能;但作为一般规则,我将不使用任何VB.NET特定功能。


2
投票

这里是上述测试的代码,但是使用System.Diagnostics.Stopwatch重做,并消除了Console.write瓶颈。

事实证明,直接广播是最快的(应该也是如此-在这种情况下它什么也没做。但是,这是一个琐碎的示例,因为很少有人希望将字符串转换为字符串。模块Module1子Main()

    Dim obj As Object = "asdfsdasdfsadfasdfasdfasdfsdasdfsadfasdfasdfdafsdfasd"
    Dim LL As New List(Of String), SWW As System.Diagnostics.Stopwatch

    LL.Clear()

    SWW = Stopwatch.StartNew()
    For i = 0 To Short.MaxValue
        LL.Add(obj.ToString)
    Next
    Console.WriteLine("obj.ToString took {0}.", SWW.ElapsedTicks)

    LL.Clear()
    SWW = Stopwatch.StartNew()
    For i = 0 To Short.MaxValue
        LL.Add(CStr(obj))
    Next
    Console.WriteLine("CStr(obj) took {0}.", SWW.ElapsedTicks)

    LL.Clear()
    SWW = Stopwatch.StartNew()
    For i = 0 To Short.MaxValue
        LL.Add(DirectCast(obj, String))
    Next
    Console.WriteLine("DirectCast(obj, String) took {0}.", SWW.ElapsedTicks)





    Console.WriteLine("---------------- Integer To String ----------- ")

    obj = 15522

    LL.Clear()
    SWW = Stopwatch.StartNew()
    For i = 0 To Short.MaxValue
        LL.Add(obj.ToString)
    Next
    Console.WriteLine("obj.ToString took {0}.", SWW.ElapsedTicks)

    LL.Clear()
    SWW = Stopwatch.StartNew()
    For i = 0 To Short.MaxValue
        LL.Add(CStr(obj))
    Next
    Console.WriteLine("CStr(obj) took {0}.", SWW.ElapsedTicks)

    LL.Clear()
    SWW = Stopwatch.StartNew()
    For i = 0 To Short.MaxValue
        Dim str As String = TryCast(obj, String)
        ' This obviously fails, as obj is not a string, which is why it is so fast.. str is then nothing
        LL.Add(str)

    Next
    Console.WriteLine("DirectCast(obj, String) took {0}.", SWW.ElapsedTicks)

    Console.Read()
End Sub

结束模块

我的结果:

(string ) : ToString : 2288; CStr: 2275; DirectCast: 1586

(integer) : ToString : 10526; CStr: 13184; TryCast: 982


2
投票

CStr与ToString之间的一个大区别是对Enum变量的处理。

CStr返回基础数字,例如“ 2”,并且ToString返回Enum名称,例如“左转右”


1
投票

它们是完全不同的两件事,CStr是一个重载函数,它将某些类型中的数据转换为字符串,而ToString调用所有.net对象都具有的方法,您可以重写该方法,但默认情况下包含该对象的名称。如果已重写ToString,则只会返回该类型的数据。


0
投票

这是我进行的一些测试的结果:

Module Module1
  Sub Main()

    Dim obj As Object = "asdfsdasdfsadfasdfasdfasdfsdasdfsadfasdfasdfdafsdfasd"
    Dim y = Now, z = Now

    y = Now
    For i = 0 To Short.MaxValue
      Console.WriteLine(obj.ToString)
    Next
    z = Now
    Dim time1 = z - y

    y = Now
    For i = 0 To Short.MaxValue
      Console.WriteLine(CStr(obj))
    Next
    z = Now

    Dim time2 = z - y
    y = Now
    For i = 0 To Short.MaxValue
      Console.WriteLine(DirectCast(obj, String))
    Next
    z = Now

    Dim time3 = z - y

    Console.WriteLine("obj.ToString took {0}.", time1)
    Console.WriteLine("CStr(obj) took {0}.", time2)
    Console.WriteLine("DirectCast(obj, String) took {0}.", time3)
    Console.Read()
  End Sub
End Module

结果:

obj.ToString() took 00:00:06.9303964.
CStr(obj) took 00:00:06.8763933.
DirectCast(obj, String) took 00:00:06.8903941.

[确定CStr是最快的,然后转到DirectCast,最后是ToString,其性能成本很高。


0
投票

我试图计时以下两个子例程(原谅我的变量命名):

 For i As Integer = 1 To 1000
        For j As Integer = 1 To 65536
            eee = aaa.ToString()
            eee = bbb.ToString()
            eee = ccc.ToString()
            eee = ddd.ToString()
            eee = Nothing
        Next
 Next

    For i As Integer = 1 To 1000
        For j As Integer = 1 To 65536
            eee = CStr(aaa)
            eee = CStr(bbb)
            eee = CStr(ccc)
            eee = CStr(ddd)
            eee = Nothing
        Next
    Next

where

    Dim aaa As Integer = 1233
    Dim bbb As Single = 445.234234234
    Dim ccc As Double = 234234.234457634
    Dim ddd As Decimal = 1231.3466734523424
    Dim eee As String = Nothing

ToString()循环需要62秒,CStr()循环需要64秒。如果您仅处理数字,我认为这的影响确实不大。我在计时过程中禁用了任何编译器优化。


0
投票

最新答案,但是没有人愿意去检查或引用Visual Basic文档,它建议与大多数答案相反。这直接来自Microsoft documentation

通常,在Convert类或单个类型结构或类上,应优先使用Visual Basic类型转换函数,而不要使用.NET Framework方法(例如ToString())。 Visual Basic函数旨在与Visual Basic代码进行最佳交互,它们还使您的源代码更短,更易于阅读。

也就是说,有时CStrToString返回之间存在差异,因此性能和可读性不是唯一的考虑因素。在另一个问题上有一个出色的answer,它描述了何时以及为何如此。转载于此:

ToString方法是返回String的标准公共方法。它是由基本Object类型定义为可重写的方法。因此,每个类都可以重写该方法以返回所需的任何内容。类重写ToString方法以使其返回对象的易于阅读的描述是很常见的。

CStr,另一方面,是转换运算符。它是CType(x,String)的简写。像其他许多运算符一样,强制转换运算符可以被任何类覆盖。不过,通常情况下,您希望转换操作返回原始对象实际值的最接近表示形式,而不是描述性字符串。

那么,您可能希望ToString返回的结果与CStr不同。对于枚举,每个成员本质上都是一个整数,因此枚举成员上的CStr与整数上的CStr相同。那就是您所期望的。但是,ToString已被重写以返回该值的更易阅读的版本。这也是您所期望的。

因此,总而言之:

当您想要最接近原始对象实际值的字符串表示形式时,应使用CStr()。如果需要该值(可能是自定义的,人类可读的版本),则应使用.ToString


-1
投票
CStr(object)是强制类型转换(等效于C#中的(string)对象),如果给出空对象或无法强制转换为字符串的对象,则将抛出esxception。但是.ToString()可以在任何类型的对象上运行(因为它是在Object类中实现的),并且如果未被当前类重写,则将返回基本的ToString()方法。在您的情况下,您必须在ID_TYPE类中重写ToString()方法并返回所需的字符串。
© www.soinside.com 2019 - 2024. All rights reserved.