Casting is the process of converting one data type to another, for example, from an Integer type to a String type. Some operations in VB.NET require specific data types to work. Casting creates the type you need. The first article in this two-part series, Casting and Data Type Conversions in VB.NET, introduces casting. This article describes the three operators you can use to cast in VB.NET - DirectCast, CType and TryCast - and compares their performance.
强制转换是将一种数据类型转换为另一种数据类型的过程 ,例如,从整数类型转换为字符串类型。 VB.NET中的某些操作需要特定的数据类型才能工作。 转换会创建您需要的类型。 这个由两部分组成的系列文章的第一篇文章VB.NET中的转换和数据类型转换介绍了转换。 本文介绍了可用于在VB.NET中进行转换的三个运算符-DirectCast,CType和TryCast-并比较了它们的性能。
Performance is one of the big differences between the three casting operators according to Microsoft and other articles. For example, Microsoft is usually careful to warn that, "DirectCast ... can provide somewhat better performance than CType when converting to and from data type Object." (Emphasis added.)
根据Microsoft和其他文章,性能是这三个铸造运营商之间的最大差异之一。 例如,Microsoft通常会小心警告:“ 在与数据类型Object进行相互转换时 ,DirectCast ...可以提供比CType更好的性能。” (强调)。
I decided to write some code to check.
我决定编写一些代码进行检查。
But first a word of caution. Dan Appleman, one of the founders of the technical book publisher Apress and a reliable technical guru, once told me that benchmarking performance is much harder to do correctly than most people realize. There are factors like machine performance, other processes that might be running in parallel, optimization like memory caching or compiler optimization, and errors in your assumptions about what the code is actually doing. In these benchmarks, I have tried to eliminate "apples and oranges" comparison errors and all tests have been run with the release build. But there still might be errors in these results. If you notice any, please let me know.
但是首先要提请注意。 丹·阿普尔曼(Dan Appleman)是技术书籍出版商Apress的创始人之一,并且是可靠的技术专家。他曾经告诉我,基准测试的性能要比大多数人意识到的要难得多。 这些因素包括机器性能,可能并行运行的其他进程,优化(例如内存缓存或编译器优化)以及您对代码实际作用的假设错误。 在这些基准测试中,我尝试消除了“苹果和橘子”的比较错误,并且所有测试都在发布版本中运行。 但是这些结果中可能仍然存在错误。 如果您发现任何问题,请告诉我。
The three casting operators are:
这三个铸造运算符是:
- DirectCast DirectCast
- CType C类型
- TryCast 试播
In practical fact, you will usually find that the requirements of your application will determine which operator you use. DirectCast and TryCast have very narrow requirements. When you use DirectCast, the type must already be known. Although the code ...
实际上,您通常会发现应用程序的需求将确定您使用的操作员。 DirectCast和TryCast具有非常狭窄的要求。 当您使用DirectCast时,必须已经知道类型。 虽然代码...
theString = DirectCast(theObject, String)
theString = DirectCast(theObject,String)
... will compile successfully if theObject isn't a string already, then the code will throw a runtime exception.
如果对象不是字符串,则...将成功编译,然后代码将引发运行时异常。
TryCast is even more restrictive because it won't work at all on "value" types such as Integer. (String is a reference type. For more on value types and reference types, see the first article in this series.) This code ...
TryCast的限制更为严格,因为它根本不适用于“值”类型,例如整数。 (字符串是一种引用类型。有关值类型和引用类型的更多信息,请参见本系列的第一篇文章。)此代码...
theInteger = TryCast(theObject, Integer)
theInteger = TryCast(theObject,Integer)
... won't even compile.
...甚至不会编译。
TryCast is useful when you're not sure what type of object you're working with. Rather than throwing an error like DirectCast, TryCast just returns Nothing. The normal practice is to test for Nothing after executing TryCast.
当您不确定所使用的对象类型时,TryCast很有用。 与其引发DirectCast之类的错误,TryCast只返回Nothing。 通常的做法是在执行TryCast之后不进行任何测试。
Only CType (and the other "Convert" operators like CInt and CBool) will convert types that don't have an inheritance relationship such as an Integer to a String:
只有CType(以及其他“转换”运算符,例如CInt和CBool)会将没有继承关系的类型(例如整数)转换为字符串:
Dim theString As String = "1"
Dim theInteger As Integer
theInteger = CType(theString, Integer)
This works because CType uses "helper functions" that aren't part of the .NET CLR (Common Language Runtime) to perform these conversions.
之所以可行,是因为CType使用不属于.NET CLR(公共语言运行时)一部分的“帮助函数”来执行这些转换。
But remember that CType will also throw an exception if theString doesn't contain something that can be converted to an Integer. If there's a possibility that the string isn't an integer like this ...
但是请记住,如果theString不包含可以转换为Integer的内容,则CType也会引发异常。 如果字符串不是这样的整数...
Dim theString As String = "George"
... then no casting operator will work. Even TryCast won't work with Integer because it's a value type. In a case like this, you would have to use validity checking, such as the TypeOf operator, to check your data before trying to cast it.
...那么没有铸造工人将工作。 即使TryCast也不能与Integer一起使用,因为它是一种值类型。 在这种情况下,您必须先使用有效性检查(例如TypeOf运算符)来检查数据,然后再尝试对其进行强制转换。
Microsoft's documentation for DirectCast specifically mentions casting with an Object type so that's what I used in my first performance test. Testing begins on the next page!
Microsoft的DirectCast文档特别提到了使用Object类型进行转换,这就是我在第一次性能测试中所使用的。 测试从下一页开始!
DirectCast will usually use an Object type, so that's what I used in my first performance test. To include TryCast in the test, I also included an If block since nearly all programs that use TryCast will have one. In this case, however, it will never be executed.
DirectCast通常将使用对象类型,因此这就是我在第一次性能测试中使用的类型。 为了在测试中包含TryCast,我还包含了一个If块,因为几乎所有使用TryCast的程序都将包含一个。 但是,在这种情况下,它将永远不会执行。
Here's the code that compares all three when casting an Object to a String:
这是在将对象转换为字符串时比较所有三个代码的代码:
Dim theTime As New Stopwatch()
Dim theString As String
Dim theObject As Object = "An Object"
Dim theIterations As Integer =
CInt(Iterations.Text) * 1000000
'
' DirectCast Test
theTime.Start()
For i = 0 To theIterations
theString = DirectCast(theObject, String)
Next
theTime.Stop()
DirectCastTime.Text =
theTime.ElapsedMilliseconds.ToString
'
' CType Test
theTime.Restart()
For i As Integer = 0 To theIterations
theString = CType(theObject, String)
Next
theTime.Stop()
CTypeTime.Text =
theTime.ElapsedMilliseconds.ToString
'
' TryCast Test
theTime.Restart()
For i As Integer = 0 To theIterations
theString = TryCast(theObject, String)
If theString Is Nothing Then
MsgBox("This should never display")
End If
Next
theTime.Stop()
TryCastTime.Text =
theTime.ElapsedMilliseconds.ToString
This initial test seems to show that Microsoft is right on target. Here's the result. (Experiments with larger and smaller numbers of iterations as well as repeated tests under different conditions didn't show any significant differences from this result.)
最初的测试似乎表明Microsoft是正确的目标。 这是结果。 (迭代次数越来越多的实验以及在不同条件下的重复测试并未显示与该结果有任何显着差异。)
--------Click Here to display the illustration--------
-------- 单击此处显示插图 --------
DirectCast and TryCast were similar at 323 and 356 milliseconds, but CType took over three times as much time at 1018 milliseconds. When casting reference types like this, you pay for the flexibility of CType in performance.
DirectCast和TryCast在323和356毫秒时相似,但是CType在1018毫秒时花费了三倍的时间。 当像这样转换引用类型时,您需要为CType在性能上的灵活性付出代价。
But does it always work this way? The Microsoft example in their page for DirectCast is mainly useful for telling you what won't work using DirectCast, not what will. Here's the Microsoft example:
但是它总是这样工作吗? 在他们的DirectCast页微软例子主要是有用的告诉你使用DirectCast,没有什么会什么都不行。 这是微软的例子:
Dim q As Object = 2.37
Dim i As Integer = CType(q, Integer)
' The following conversion fails at run time
Dim j As Integer = DirectCast(q, Integer)
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control
' The following conversion succeeds.
c = DirectCast(f, System.Windows.Forms.Control)
In other words, you can't use DirectCast (or TryCast, although they don't mention it here) to cast an Object type to an Integer type, but you can use DirectCast to cast a Form type to a Control type.
换句话说,您不能使用DirectCast(或TryCast,尽管此处未提及)将Object类型转换为Integer类型,但可以使用DirectCast将Form类型转换为Control类型。
Let's check the performance of Microsoft's example of what will work with DirectCast. Using the same code template shown above, substitute ...
让我们来看看什么将与DirectCast工作,微软的例子的性能。 使用上面显示的相同代码模板,替换...
c = DirectCast(f, System.Windows.Forms.Control)
... into the code along with similar substitutions for CType and TryCast. The results are a little surprising.
...以及类似的CType和TryCast替代代码。 结果有点令人惊讶。
--------Click Here to display the illustration--------
-------- 单击此处显示插图 --------
DirectCast was actually the slowest of the three choices at 145 milliseconds. CType is just a little quicker at 127 milliseconds but TryCast, including an If block, is the quickest at 77 milliseconds. I also tried writing my own objects:
DirectCast实际上是这三个选择中最慢的,为145毫秒。 CType的速度只有127毫秒,但是TryCast(包括If块)最快的是77毫秒。 我还尝试编写自己的对象:
Class ParentClass
...
End Class
Class ChildClass
Inherits ParentClass
...
End Class
I got similar results. It appears that if you're not casting an Object type, you're better off not using DirectCast.
我得到了类似的结果。 看来,如果不强制转换Object类型,最好不要使用DirectCast。
翻译自: https://www.thoughtco.com/casting-and-data-type-conversions-vbnet-3424292