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

时间:2009-06-11 07:57:51

标签: vb.net casting

我想知道哪个更有效,使用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

9 个答案:

答案 0 :(得分:12)

来自here(不能说更好):

  

CStr是关键字,而ToString是   功能(方法)。 CStr已编译完成   内联,它创建代码依赖   在传递的对象的类型上。它的   主要是因为人们习惯了   它来自以前的VB版本。一世   还没有在.Net中使用过CStr   (因为它的作用并不明显   在哪些情况下,它也没有   非常好的记录)。

     

差异取决于哪个   你使用的ToString函数。各种类型   可以拥有它自己的实现。

答案 1 :(得分:8)

为了便于阅读,如果我需要在VB.NET中编写代码(我是C#程序员),我会尽可能避免使用VB特定的关键字/函数。通过仅使用.NET类和方法,用于在其他.NET语言中开发的人员可以更容易理解您的代码。更不用说这些功能主要是为了与VB6兼容,与.NET的做法相比,它们看起来有点不合适。

当然可能有一些合理的例外,有时VB.NET真的很容易做某些任务,利用这个可以很方便;但作为一个基本的规则,我不会使用任何VB.NET特定的功能。

答案 2 :(得分:2)

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

事实证明直播是最快的(也应该是 - 在这种情况下它没有做任何事情。但是它是一个平凡的例子,因为它很少你想要将字符串转换为字符串。转换 模块模块1     Sub 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

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

它们是两个完全不同的东西,CStr是一个重载函数,它将某些类型的数据转换为字符串,而ToString调用所有.net对象都有的方法,你可以覆盖但默认情况下包含的名称是宾语。 ToString只会在被覆盖的情况下返回类型的数据。

答案 5 :(得分: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,性能成本最高。

答案 6 :(得分: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

,其中

    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秒。如果你只处理数字,我认为这真的不是一个巨大的影响。我在计时过程中禁用了任何编译器优化。

答案 7 :(得分: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

答案 8 :(得分:-2)

CStr(object)是一个强制转换(相当于C#中的(字符串)对象),如果给定一个null obejct或一个无法转换为字符串的对象,则抛出esxception。但是.ToString()将适用于任何类型的对象(因为它在Object类中实现),如果没有被当前类覆盖,则返回基本的ToString()方法。在您的情况下,您必须覆盖ID_TYPE类中的ToString()方法并返回所需的字符串。