1' Licensed to the .NET Foundation under one or more agreements.
2' The .NET Foundation licenses this file to you under the MIT license.
3' See the LICENSE file in the project root for more information.
4
5Imports System
6Imports System.ComponentModel
7Imports System.Diagnostics
8Imports System.Reflection
9
10Imports Microsoft.VisualBasic.CompilerServices.Symbols
11Imports Microsoft.VisualBasic.CompilerServices.ConversionResolution
12Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils
13Imports Microsoft.VisualBasic.CompilerServices.Utils
14Imports Container = Microsoft.VisualBasic.CompilerServices.Symbols.Container
15
16Namespace Global.Microsoft.VisualBasic.CompilerServices
17    <Global.System.Diagnostics.DebuggerNonUserCode()>
18    <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Never)>
19    Public Class Conversions
20        Private Sub New()
21        End Sub
22        Private Shared Function GetEnumValue(value As Object) As Object
23            Dim underlyingType As Type = System.Enum.GetUnderlyingType(value.GetType())
24            If underlyingType.Equals(GetType(SByte)) Then
25                Return DirectCast(value, SByte)
26            ElseIf underlyingType.Equals(GetType(Byte)) Then
27                Return DirectCast(value, Byte)
28            ElseIf underlyingType.Equals(GetType(Global.System.Int16)) Then
29                Return DirectCast(value, Global.System.Int16)
30            ElseIf underlyingType.Equals(GetType(Global.System.UInt16)) Then
31                Return DirectCast(value, Global.System.UInt16)
32            ElseIf underlyingType.Equals(GetType(Global.System.Int32)) Then
33                Return DirectCast(value, Global.System.Int32)
34            ElseIf underlyingType.Equals(GetType(Global.System.UInt32)) Then
35                Return DirectCast(value, Global.System.UInt32)
36            ElseIf underlyingType.Equals(GetType(Global.System.Int64)) Then
37                Return DirectCast(value, Global.System.Int64)
38            ElseIf underlyingType.Equals(GetType(Global.System.UInt64)) Then
39                Return DirectCast(value, Global.System.UInt64)
40            Else
41                Throw New Global.System.InvalidCastException
42            End If
43        End Function
44        Public Shared Function ToBoolean(value As String) As Boolean
45            If value Is Nothing Then
46                value = ""
47            End If
48            Try
49                Dim loc As Global.System.Globalization.CultureInfo = GetCultureInfo()
50                If loc.CompareInfo.Compare(value, Boolean.FalseString, Global.System.Globalization.CompareOptions.IgnoreCase) = 0 Then
51                    Return False
52                ElseIf loc.CompareInfo.Compare(value, Boolean.TrueString, Global.System.Globalization.CompareOptions.IgnoreCase) = 0 Then
53                    Return True
54                End If
55                Dim i64Value As Global.System.Int64
56                If IsHexOrOctValue(value, i64Value) Then
57                    Return CBool(i64Value)
58                End If
59                Return CBool(ParseDouble(value))
60            Catch e As Global.System.FormatException
61                Throw New Global.System.InvalidCastException(e.Message, e)
62            End Try
63        End Function
64        Public Shared Function ToBoolean(value As Object) As Boolean
65            If value Is Nothing Then
66                Return False
67            End If
68            If TypeOf value Is Global.System.Enum Then
69                value = GetEnumValue(value)
70            End If
71            If TypeOf value Is Boolean Then
72                Return CBool(DirectCast(value, Boolean))
73            ElseIf TypeOf value Is SByte Then
74                Return CBool(DirectCast(value, SByte))
75            ElseIf TypeOf value Is Byte Then
76                Return CBool(DirectCast(value, Byte))
77            ElseIf TypeOf value Is Global.System.Int16 Then
78                Return CBool(DirectCast(value, Global.System.Int16))
79            ElseIf TypeOf value Is Global.System.UInt16 Then
80                Return CBool(DirectCast(value, Global.System.UInt16))
81            ElseIf TypeOf value Is Global.System.Int32 Then
82                Return CBool(DirectCast(value, Global.System.Int32))
83            ElseIf TypeOf value Is Global.System.UInt32 Then
84                Return CBool(DirectCast(value, Global.System.UInt32))
85            ElseIf TypeOf value Is Global.System.Int64 Then
86                Return CBool(DirectCast(value, Global.System.Int64))
87            ElseIf TypeOf value Is Global.System.UInt64 Then
88                Return CBool(DirectCast(value, Global.System.UInt64))
89            ElseIf TypeOf value Is Decimal Then
90                Return CBool(DirectCast(value, Global.System.Decimal))
91            ElseIf TypeOf value Is Single Then
92                Return CBool(DirectCast(value, Single))
93            ElseIf TypeOf value Is Double Then
94                Return CBool(DirectCast(value, Double))
95            ElseIf TypeOf value Is String Then
96                Return CBool(DirectCast(value, String))
97            End If
98            Throw New Global.System.InvalidCastException()
99        End Function
100        Public Shared Function ToByte(value As String) As Byte
101            If value Is Nothing Then
102                Return 0
103            End If
104            Try
105                Dim i64Value As Global.System.Int64
106                If IsHexOrOctValue(value, i64Value) Then
107                    Return CByte(i64Value)
108                End If
109                Return CByte(ParseDouble(value))
110            Catch e As Global.System.FormatException
111                Throw New Global.System.InvalidCastException(e.Message, e)
112            End Try
113        End Function
114        Public Shared Function ToByte(value As Object) As Byte
115            If value Is Nothing Then
116                Return 0
117            End If
118            If TypeOf value Is Global.System.Enum Then
119                value = GetEnumValue(value)
120            End If
121            If TypeOf value Is Boolean Then
122                Return CByte(DirectCast(value, Boolean))
123            ElseIf TypeOf value Is SByte Then
124                Return CByte(DirectCast(value, SByte))
125            ElseIf TypeOf value Is Byte Then
126                Return CByte(DirectCast(value, Byte))
127            ElseIf TypeOf value Is Global.System.Int16 Then
128                Return CByte(DirectCast(value, Global.System.Int16))
129            ElseIf TypeOf value Is Global.System.UInt16 Then
130                Return CByte(DirectCast(value, Global.System.UInt16))
131            ElseIf TypeOf value Is Global.System.Int32 Then
132                Return CByte(DirectCast(value, Global.System.Int32))
133            ElseIf TypeOf value Is Global.System.UInt32 Then
134                Return CByte(DirectCast(value, Global.System.UInt32))
135            ElseIf TypeOf value Is Global.System.Int64 Then
136                Return CByte(DirectCast(value, Global.System.Int64))
137            ElseIf TypeOf value Is Global.System.UInt64 Then
138                Return CByte(DirectCast(value, Global.System.UInt64))
139            ElseIf TypeOf value Is Decimal Then
140                Return CByte(DirectCast(value, Global.System.Decimal))
141            ElseIf TypeOf value Is Single Then
142                Return CByte(DirectCast(value, Single))
143            ElseIf TypeOf value Is Double Then
144                Return CByte(DirectCast(value, Double))
145            ElseIf TypeOf value Is String Then
146                Return CByte(DirectCast(value, String))
147            End If
148            Throw New Global.System.InvalidCastException()
149        End Function
150        <Global.System.CLSCompliant(False)>
151        Public Shared Function ToSByte(value As String) As SByte
152            If value Is Nothing Then
153                Return 0
154            End If
155            Try
156                Dim i64Value As Global.System.Int64
157                If IsHexOrOctValue(value, i64Value) Then
158                    Return CSByte(i64Value)
159                End If
160                Return CSByte(ParseDouble(value))
161            Catch e As Global.System.FormatException
162                Throw New Global.System.InvalidCastException(e.Message, e)
163            End Try
164        End Function
165        <Global.System.CLSCompliant(False)>
166        Public Shared Function ToSByte(value As Object) As SByte
167            If value Is Nothing Then
168                Return 0
169            End If
170            If TypeOf value Is Global.System.Enum Then
171                value = GetEnumValue(value)
172            End If
173            If TypeOf value Is Boolean Then
174                Return CSByte(DirectCast(value, Boolean))
175            ElseIf TypeOf value Is SByte Then
176                Return CSByte(DirectCast(value, SByte))
177            ElseIf TypeOf value Is Byte Then
178                Return CSByte(DirectCast(value, Byte))
179            ElseIf TypeOf value Is Global.System.Int16 Then
180                Return CSByte(DirectCast(value, Global.System.Int16))
181            ElseIf TypeOf value Is Global.System.UInt16 Then
182                Return CSByte(DirectCast(value, Global.System.UInt16))
183            ElseIf TypeOf value Is Global.System.Int32 Then
184                Return CSByte(DirectCast(value, Global.System.Int32))
185            ElseIf TypeOf value Is Global.System.UInt32 Then
186                Return CSByte(DirectCast(value, Global.System.UInt32))
187            ElseIf TypeOf value Is Global.System.Int64 Then
188                Return CSByte(DirectCast(value, Global.System.Int64))
189            ElseIf TypeOf value Is Global.System.UInt64 Then
190                Return CSByte(DirectCast(value, Global.System.UInt64))
191            ElseIf TypeOf value Is Decimal Then
192                Return CSByte(DirectCast(value, Global.System.Decimal))
193            ElseIf TypeOf value Is Single Then
194                Return CSByte(DirectCast(value, Single))
195            ElseIf TypeOf value Is Double Then
196                Return CSByte(DirectCast(value, Double))
197            ElseIf TypeOf value Is String Then
198                Return CSByte(DirectCast(value, String))
199            End If
200            Throw New Global.System.InvalidCastException()
201        End Function
202        Public Shared Function ToShort(value As String) As Short
203            If value Is Nothing Then
204                Return 0
205            End If
206            Try
207                Dim i64Value As Global.System.Int64
208                If IsHexOrOctValue(value, i64Value) Then
209                    Return CShort(i64Value)
210                End If
211                Return CShort(ParseDouble(value))
212            Catch e As Global.System.FormatException
213                Throw New Global.System.InvalidCastException(e.Message, e)
214            End Try
215        End Function
216        Public Shared Function ToShort(value As Object) As Short
217            If value Is Nothing Then
218                Return 0
219            End If
220            If TypeOf value Is Global.System.Enum Then
221                value = GetEnumValue(value)
222            End If
223            If TypeOf value Is Boolean Then
224                Return CShort(DirectCast(value, Boolean))
225            ElseIf TypeOf value Is SByte Then
226                Return CShort(DirectCast(value, SByte))
227            ElseIf TypeOf value Is Byte Then
228                Return CShort(DirectCast(value, Byte))
229            ElseIf TypeOf value Is Global.System.Int16 Then
230                Return CShort(DirectCast(value, Global.System.Int16))
231            ElseIf TypeOf value Is Global.System.UInt16 Then
232                Return CShort(DirectCast(value, Global.System.UInt16))
233            ElseIf TypeOf value Is Global.System.Int32 Then
234                Return CShort(DirectCast(value, Global.System.Int32))
235            ElseIf TypeOf value Is Global.System.UInt32 Then
236                Return CShort(DirectCast(value, Global.System.UInt32))
237            ElseIf TypeOf value Is Global.System.Int64 Then
238                Return CShort(DirectCast(value, Global.System.Int64))
239            ElseIf TypeOf value Is Global.System.UInt64 Then
240                Return CShort(DirectCast(value, Global.System.UInt64))
241            ElseIf TypeOf value Is Decimal Then
242                Return CShort(DirectCast(value, Global.System.Decimal))
243            ElseIf TypeOf value Is Single Then
244                Return CShort(DirectCast(value, Single))
245            ElseIf TypeOf value Is Double Then
246                Return CShort(DirectCast(value, Double))
247            ElseIf TypeOf value Is String Then
248                Return CShort(DirectCast(value, String))
249            End If
250            Throw New Global.System.InvalidCastException()
251        End Function
252        <Global.System.CLSCompliant(False)>
253        Public Shared Function ToUShort(value As String) As UShort
254            If value Is Nothing Then
255                Return 0
256            End If
257            Try
258                Dim i64Value As Global.System.Int64
259                If IsHexOrOctValue(value, i64Value) Then
260                    Return CUShort(i64Value)
261                End If
262                Return CUShort(ParseDouble(value))
263            Catch e As Global.System.FormatException
264                Throw New Global.System.InvalidCastException(e.Message, e)
265            End Try
266        End Function
267        <Global.System.CLSCompliant(False)>
268        Public Shared Function ToUShort(value As Object) As UShort
269            If value Is Nothing Then
270                Return 0
271            End If
272            If TypeOf value Is Global.System.Enum Then
273                value = GetEnumValue(value)
274            End If
275            If TypeOf value Is Boolean Then
276                Return CUShort(DirectCast(value, Boolean))
277            ElseIf TypeOf value Is SByte Then
278                Return CUShort(DirectCast(value, SByte))
279            ElseIf TypeOf value Is Byte Then
280                Return CUShort(DirectCast(value, Byte))
281            ElseIf TypeOf value Is Global.System.Int16 Then
282                Return CUShort(DirectCast(value, Global.System.Int16))
283            ElseIf TypeOf value Is Global.System.UInt16 Then
284                Return CUShort(DirectCast(value, Global.System.UInt16))
285            ElseIf TypeOf value Is Global.System.Int32 Then
286                Return CUShort(DirectCast(value, Global.System.Int32))
287            ElseIf TypeOf value Is Global.System.UInt32 Then
288                Return CUShort(DirectCast(value, Global.System.UInt32))
289            ElseIf TypeOf value Is Global.System.Int64 Then
290                Return CUShort(DirectCast(value, Global.System.Int64))
291            ElseIf TypeOf value Is Global.System.UInt64 Then
292                Return CUShort(DirectCast(value, Global.System.UInt64))
293            ElseIf TypeOf value Is Decimal Then
294                Return CUShort(DirectCast(value, Global.System.Decimal))
295            ElseIf TypeOf value Is Single Then
296                Return CUShort(DirectCast(value, Single))
297            ElseIf TypeOf value Is Double Then
298                Return CUShort(DirectCast(value, Double))
299            ElseIf TypeOf value Is String Then
300                Return CUShort(DirectCast(value, String))
301            End If
302            Throw New Global.System.InvalidCastException()
303        End Function
304        Public Shared Function ToInteger(value As String) As Integer
305            If value Is Nothing Then
306                Return 0
307            End If
308            Try
309                Dim i64Value As Global.System.Int64
310                If IsHexOrOctValue(value, i64Value) Then
311                    Return CInt(i64Value)
312                End If
313                Return CInt(ParseDouble(value))
314            Catch e As Global.System.FormatException
315                Throw New Global.System.InvalidCastException(e.Message, e)
316            End Try
317        End Function
318        Public Shared Function ToInteger(value As Object) As Integer
319            If value Is Nothing Then
320                Return 0
321            End If
322            If TypeOf value Is Global.System.Enum Then
323                value = GetEnumValue(value)
324            End If
325            If TypeOf value Is Boolean Then
326                Return CInt(DirectCast(value, Boolean))
327            ElseIf TypeOf value Is SByte Then
328                Return CInt(DirectCast(value, SByte))
329            ElseIf TypeOf value Is Byte Then
330                Return CInt(DirectCast(value, Byte))
331            ElseIf TypeOf value Is Global.System.Int16 Then
332                Return CInt(DirectCast(value, Global.System.Int16))
333            ElseIf TypeOf value Is Global.System.UInt16 Then
334                Return CInt(DirectCast(value, Global.System.UInt16))
335            ElseIf TypeOf value Is Global.System.Int32 Then
336                Return CInt(DirectCast(value, Global.System.Int32))
337            ElseIf TypeOf value Is Global.System.UInt32 Then
338                Return CInt(DirectCast(value, Global.System.UInt32))
339            ElseIf TypeOf value Is Global.System.Int64 Then
340                Return CInt(DirectCast(value, Global.System.Int64))
341            ElseIf TypeOf value Is Global.System.UInt64 Then
342                Return CInt(DirectCast(value, Global.System.UInt64))
343            ElseIf TypeOf value Is Decimal Then
344                Return CInt(DirectCast(value, Global.System.Decimal))
345            ElseIf TypeOf value Is Single Then
346                Return CInt(DirectCast(value, Single))
347            ElseIf TypeOf value Is Double Then
348                Return CInt(DirectCast(value, Double))
349            ElseIf TypeOf value Is String Then
350                Return CInt(DirectCast(value, String))
351            End If
352            Throw New Global.System.InvalidCastException()
353        End Function
354        <Global.System.CLSCompliant(False)>
355        Public Shared Function ToUInteger(value As String) As UInteger
356            If value Is Nothing Then
357                Return 0
358            End If
359            Try
360                Dim i64Value As Global.System.Int64
361                If IsHexOrOctValue(value, i64Value) Then
362                    Return CUInt(i64Value)
363                End If
364                Return CUInt(ParseDouble(value))
365            Catch e As Global.System.FormatException
366                Throw New Global.System.InvalidCastException(e.Message, e)
367            End Try
368        End Function
369        <Global.System.CLSCompliant(False)>
370        Public Shared Function ToUInteger(value As Object) As UInteger
371            If value Is Nothing Then
372                Return 0
373            End If
374            If TypeOf value Is Global.System.Enum Then
375                value = GetEnumValue(value)
376            End If
377            If TypeOf value Is Boolean Then
378                Return CUInt(DirectCast(value, Boolean))
379            ElseIf TypeOf value Is SByte Then
380                Return CUInt(DirectCast(value, SByte))
381            ElseIf TypeOf value Is Byte Then
382                Return CUInt(DirectCast(value, Byte))
383            ElseIf TypeOf value Is Global.System.Int16 Then
384                Return CUInt(DirectCast(value, Global.System.Int16))
385            ElseIf TypeOf value Is Global.System.UInt16 Then
386                Return CUInt(DirectCast(value, Global.System.UInt16))
387            ElseIf TypeOf value Is Global.System.Int32 Then
388                Return CUInt(DirectCast(value, Global.System.Int32))
389            ElseIf TypeOf value Is Global.System.UInt32 Then
390                Return CUInt(DirectCast(value, Global.System.UInt32))
391            ElseIf TypeOf value Is Global.System.Int64 Then
392                Return CUInt(DirectCast(value, Global.System.Int64))
393            ElseIf TypeOf value Is Global.System.UInt64 Then
394                Return CUInt(DirectCast(value, Global.System.UInt64))
395            ElseIf TypeOf value Is Decimal Then
396                Return CUInt(DirectCast(value, Global.System.Decimal))
397            ElseIf TypeOf value Is Single Then
398                Return CUInt(DirectCast(value, Single))
399            ElseIf TypeOf value Is Double Then
400                Return CUInt(DirectCast(value, Double))
401            ElseIf TypeOf value Is String Then
402                Return CUInt(DirectCast(value, String))
403            End If
404            Throw New Global.System.InvalidCastException()
405        End Function
406        Public Shared Function ToLong(value As String) As Long
407            If (value Is Nothing) Then
408                Return 0
409            End If
410            Try
411                Dim i64Value As Global.System.Int64
412                If IsHexOrOctValue(value, i64Value) Then
413                    Return CLng(i64Value)
414                End If
415                Return CLng(ParseDecimal(value, Nothing))
416            Catch e As Global.System.FormatException
417                Throw New Global.System.InvalidCastException(e.Message, e)
418            End Try
419        End Function
420        Public Shared Function ToLong(value As Object) As Long
421            If value Is Nothing Then
422                Return 0
423            End If
424            If TypeOf value Is Global.System.Enum Then
425                value = GetEnumValue(value)
426            End If
427            If TypeOf value Is Boolean Then
428                Return CLng(DirectCast(value, Boolean))
429            ElseIf TypeOf value Is SByte Then
430                Return CLng(DirectCast(value, SByte))
431            ElseIf TypeOf value Is Byte Then
432                Return CLng(DirectCast(value, Byte))
433            ElseIf TypeOf value Is Global.System.Int16 Then
434                Return CLng(DirectCast(value, Global.System.Int16))
435            ElseIf TypeOf value Is Global.System.UInt16 Then
436                Return CLng(DirectCast(value, Global.System.UInt16))
437            ElseIf TypeOf value Is Global.System.Int32 Then
438                Return CLng(DirectCast(value, Global.System.Int32))
439            ElseIf TypeOf value Is Global.System.UInt32 Then
440                Return CLng(DirectCast(value, Global.System.UInt32))
441            ElseIf TypeOf value Is Global.System.Int64 Then
442                Return CLng(DirectCast(value, Global.System.Int64))
443            ElseIf TypeOf value Is Global.System.UInt64 Then
444                Return CLng(DirectCast(value, Global.System.UInt64))
445            ElseIf TypeOf value Is Decimal Then
446                Return CLng(DirectCast(value, Global.System.Decimal))
447            ElseIf TypeOf value Is Single Then
448                Return CLng(DirectCast(value, Single))
449            ElseIf TypeOf value Is Double Then
450                Return CLng(DirectCast(value, Double))
451            ElseIf TypeOf value Is String Then
452                Return CLng(DirectCast(value, String))
453            End If
454            Throw New Global.System.InvalidCastException()
455        End Function
456        <Global.System.CLSCompliant(False)>
457        Public Shared Function ToULong(value As String) As ULong
458            If (value Is Nothing) Then
459                Return 0
460            End If
461            Try
462                Dim ui64Value As Global.System.UInt64
463                If IsHexOrOctValue(value, ui64Value) Then
464                    Return CULng(ui64Value)
465                End If
466                Return CULng(ParseDecimal(value, Nothing))
467            Catch e As Global.System.FormatException
468                Throw New Global.System.InvalidCastException(e.Message, e)
469            End Try
470        End Function
471        <Global.System.CLSCompliant(False)>
472        Public Shared Function ToULong(value As Object) As ULong
473            If value Is Nothing Then
474                Return 0
475            End If
476            If TypeOf value Is Global.System.Enum Then
477                value = GetEnumValue(value)
478            End If
479            If TypeOf value Is Boolean Then
480                Return CULng(DirectCast(value, Boolean))
481            ElseIf TypeOf value Is SByte Then
482                Return CULng(DirectCast(value, SByte))
483            ElseIf TypeOf value Is Byte Then
484                Return CULng(DirectCast(value, Byte))
485            ElseIf TypeOf value Is Global.System.Int16 Then
486                Return CULng(DirectCast(value, Global.System.Int16))
487            ElseIf TypeOf value Is Global.System.UInt16 Then
488                Return CULng(DirectCast(value, Global.System.UInt16))
489            ElseIf TypeOf value Is Global.System.Int32 Then
490                Return CULng(DirectCast(value, Global.System.Int32))
491            ElseIf TypeOf value Is Global.System.UInt32 Then
492                Return CULng(DirectCast(value, Global.System.UInt32))
493            ElseIf TypeOf value Is Global.System.Int64 Then
494                Return CULng(DirectCast(value, Global.System.Int64))
495            ElseIf TypeOf value Is Global.System.UInt64 Then
496                Return CULng(DirectCast(value, Global.System.UInt64))
497            ElseIf TypeOf value Is Decimal Then
498                Return CULng(DirectCast(value, Global.System.Decimal))
499            ElseIf TypeOf value Is Single Then
500                Return CULng(DirectCast(value, Single))
501            ElseIf TypeOf value Is Double Then
502                Return CULng(DirectCast(value, Double))
503            ElseIf TypeOf value Is String Then
504                Return CULng(DirectCast(value, String))
505            End If
506            Throw New Global.System.InvalidCastException()
507        End Function
508        Public Shared Function ToDecimal(value As Boolean) As Decimal
509            If value Then
510                Return -1D
511            Else
512                Return 0D
513            End If
514        End Function
515        Public Shared Function ToDecimal(value As String) As Decimal
516            If value Is Nothing Then
517                Return 0D
518            End If
519            Try
520                Dim i64Value As Global.System.Int64
521                If IsHexOrOctValue(value, i64Value) Then
522                    Return CDec(i64Value)
523                End If
524                Return ParseDecimal(value, Nothing)
525            Catch e1 As Global.System.OverflowException
526                Throw e1
527            Catch e2 As Global.System.FormatException
528                Throw New Global.System.InvalidCastException(e2.Message, e2)
529            End Try
530        End Function
531        Public Shared Function ToDecimal(value As Object) As Decimal
532            If value Is Nothing Then
533                Return 0D
534            End If
535            If TypeOf value Is Global.System.Enum Then
536                value = GetEnumValue(value)
537            End If
538            If TypeOf value Is Boolean Then
539                Return CDec(DirectCast(value, Boolean))
540            ElseIf TypeOf value Is SByte Then
541                Return CDec(DirectCast(value, SByte))
542            ElseIf TypeOf value Is Byte Then
543                Return CDec(DirectCast(value, Byte))
544            ElseIf TypeOf value Is Global.System.Int16 Then
545                Return CDec(DirectCast(value, Global.System.Int16))
546            ElseIf TypeOf value Is Global.System.UInt16 Then
547                Return CDec(DirectCast(value, Global.System.UInt16))
548            ElseIf TypeOf value Is Global.System.Int32 Then
549                Return CDec(DirectCast(value, Global.System.Int32))
550            ElseIf TypeOf value Is Global.System.UInt32 Then
551                Return CDec(DirectCast(value, Global.System.UInt32))
552            ElseIf TypeOf value Is Global.System.Int64 Then
553                Return CDec(DirectCast(value, Global.System.Int64))
554            ElseIf TypeOf value Is Global.System.UInt64 Then
555                Return CDec(DirectCast(value, Global.System.UInt64))
556            ElseIf TypeOf value Is Decimal Then
557                Return CDec(DirectCast(value, Global.System.Decimal))
558            ElseIf TypeOf value Is Single Then
559                Return CDec(DirectCast(value, Single))
560            ElseIf TypeOf value Is Double Then
561                Return CDec(DirectCast(value, Double))
562            ElseIf TypeOf value Is String Then
563                Return CDec(DirectCast(value, String))
564            End If
565            Throw New Global.System.InvalidCastException()
566        End Function
567        Private Shared Function ParseDecimal(value As String, numberFormat As Global.System.Globalization.NumberFormatInfo) As Decimal
568            Dim normalizedNumberFormat As Global.System.Globalization.NumberFormatInfo
569            Dim culture As Global.System.Globalization.CultureInfo = GetCultureInfo()
570            If numberFormat Is Nothing Then
571                numberFormat = culture.NumberFormat
572            End If
573            normalizedNumberFormat = GetNormalizedNumberFormat(numberFormat)
574            Const flags As Global.System.Globalization.NumberStyles =
575                    Global.System.Globalization.NumberStyles.AllowDecimalPoint Or
576                    Global.System.Globalization.NumberStyles.AllowExponent Or
577                    Global.System.Globalization.NumberStyles.AllowLeadingSign Or
578                    Global.System.Globalization.NumberStyles.AllowLeadingWhite Or
579                    Global.System.Globalization.NumberStyles.AllowThousands Or
580                    Global.System.Globalization.NumberStyles.AllowTrailingSign Or
581                    Global.System.Globalization.NumberStyles.AllowParentheses Or
582                    Global.System.Globalization.NumberStyles.AllowTrailingWhite Or
583                    Global.System.Globalization.NumberStyles.AllowCurrencySymbol
584            value = ToHalfwidthNumbers(value, culture)
585            Try
586                Return Global.System.Decimal.Parse(value, flags, normalizedNumberFormat)
587            Catch formatEx As Global.System.FormatException When Not (numberFormat Is normalizedNumberFormat)
588                Return Global.System.Decimal.Parse(value, flags, numberFormat)
589            Catch ex As Global.System.Exception
590                Throw ex
591            End Try
592        End Function
593        Private Shared Function GetNormalizedNumberFormat(inNumberFormat As Global.System.Globalization.NumberFormatInfo) As Global.System.Globalization.NumberFormatInfo
594            Dim outNumberFormat As Global.System.Globalization.NumberFormatInfo
595            With inNumberFormat
596                If (Not .CurrencyDecimalSeparator Is Nothing) AndAlso
597                   (Not .NumberDecimalSeparator Is Nothing) AndAlso
598                   (Not .CurrencyGroupSeparator Is Nothing) AndAlso
599                   (Not .NumberGroupSeparator Is Nothing) AndAlso
600                   (.CurrencyDecimalSeparator.Length = 1) AndAlso
601                   (.NumberDecimalSeparator.Length = 1) AndAlso
602                   (.CurrencyGroupSeparator.Length = 1) AndAlso
603                   (.NumberGroupSeparator.Length = 1) AndAlso
604                   (.CurrencyDecimalSeparator.Chars(0) = .NumberDecimalSeparator.Chars(0)) AndAlso
605                   (.CurrencyGroupSeparator.Chars(0) = .NumberGroupSeparator.Chars(0)) AndAlso
606                   (.CurrencyDecimalDigits = .NumberDecimalDigits) Then
607                    Return inNumberFormat
608                End If
609            End With
610            With inNumberFormat
611                If (Not .CurrencyDecimalSeparator Is Nothing) AndAlso
612                   (Not .NumberDecimalSeparator Is Nothing) AndAlso
613                   (.CurrencyDecimalSeparator.Length = .NumberDecimalSeparator.Length) AndAlso
614                   (Not .CurrencyGroupSeparator Is Nothing) AndAlso
615                   (Not .NumberGroupSeparator Is Nothing) AndAlso
616                   (.CurrencyGroupSeparator.Length = .NumberGroupSeparator.Length) Then
617                    Dim i As Integer
618                    For i = 0 To .CurrencyDecimalSeparator.Length - 1
619                        If (.CurrencyDecimalSeparator.Chars(i) <> .NumberDecimalSeparator.Chars(i)) Then GoTo MisMatch
620                    Next
621                    For i = 0 To .CurrencyGroupSeparator.Length - 1
622                        If (.CurrencyGroupSeparator.Chars(i) <> .NumberGroupSeparator.Chars(i)) Then GoTo MisMatch
623                    Next
624                    Return inNumberFormat
625                End If
626            End With
627MisMatch:
628            outNumberFormat = DirectCast(inNumberFormat.Clone, Global.System.Globalization.NumberFormatInfo)
629            With outNumberFormat
630                .CurrencyDecimalSeparator = .NumberDecimalSeparator
631                .CurrencyGroupSeparator = .NumberGroupSeparator
632                .CurrencyDecimalDigits = .NumberDecimalDigits
633            End With
634            Return outNumberFormat
635        End Function
636        Public Shared Function ToSingle(value As String) As Single
637            If value Is Nothing Then
638                Return 0
639            End If
640            Try
641                Dim i64Value As Global.System.Int64
642                If IsHexOrOctValue(value, i64Value) Then
643                    Return CSng(i64Value)
644                End If
645                Dim result As Double = ParseDouble(value)
646                If (result < Global.System.Single.MinValue OrElse result > Global.System.Single.MaxValue) AndAlso
647                   Not Global.System.Double.IsInfinity(result) Then
648                    Throw New Global.System.OverflowException
649                End If
650                Return CSng(result)
651            Catch e As Global.System.FormatException
652                Throw New Global.System.InvalidCastException(e.Message, e)
653            End Try
654        End Function
655        Public Shared Function ToSingle(value As Object) As Single
656            If value Is Nothing Then
657                Return 0
658            End If
659            If TypeOf value Is Global.System.Enum Then
660                value = GetEnumValue(value)
661            End If
662            If TypeOf value Is Boolean Then
663                Return CSng(DirectCast(value, Boolean))
664            ElseIf TypeOf value Is SByte Then
665                Return CSng(DirectCast(value, SByte))
666            ElseIf TypeOf value Is Byte Then
667                Return CSng(DirectCast(value, Byte))
668            ElseIf TypeOf value Is Global.System.Int16 Then
669                Return CSng(DirectCast(value, Global.System.Int16))
670            ElseIf TypeOf value Is Global.System.UInt16 Then
671                Return CSng(DirectCast(value, Global.System.UInt16))
672            ElseIf TypeOf value Is Global.System.Int32 Then
673                Return CSng(DirectCast(value, Global.System.Int32))
674            ElseIf TypeOf value Is Global.System.UInt32 Then
675                Return CSng(DirectCast(value, Global.System.UInt32))
676            ElseIf TypeOf value Is Global.System.Int64 Then
677                Return CSng(DirectCast(value, Global.System.Int64))
678            ElseIf TypeOf value Is Global.System.UInt64 Then
679                Return CSng(DirectCast(value, Global.System.UInt64))
680            ElseIf TypeOf value Is Decimal Then
681                Return CSng(DirectCast(value, Global.System.Decimal))
682            ElseIf TypeOf value Is Single Then
683                Return CSng(DirectCast(value, Single))
684            ElseIf TypeOf value Is Double Then
685                Return CSng(DirectCast(value, Double))
686            ElseIf TypeOf value Is String Then
687                Return CSng(DirectCast(value, String))
688            End If
689            Throw New Global.System.InvalidCastException()
690        End Function
691        Public Shared Function ToDouble(value As String) As Double
692            If value Is Nothing Then
693                Return 0
694            End If
695            Try
696                Dim i64Value As Global.System.Int64
697                If IsHexOrOctValue(value, i64Value) Then
698                    Return CDbl(i64Value)
699                End If
700                Return ParseDouble(value)
701            Catch e As Global.System.FormatException
702                Throw New Global.System.InvalidCastException(e.Message, e)
703            End Try
704        End Function
705        Public Shared Function ToDouble(value As Object) As Double
706            If value Is Nothing Then
707                Return 0
708            End If
709            If TypeOf value Is Global.System.Enum Then
710                value = GetEnumValue(value)
711            End If
712            If TypeOf value Is Boolean Then
713                Return CDbl(DirectCast(value, Boolean))
714            ElseIf TypeOf value Is SByte Then
715                Return CDbl(DirectCast(value, SByte))
716            ElseIf TypeOf value Is Byte Then
717                Return CDbl(DirectCast(value, Byte))
718            ElseIf TypeOf value Is Global.System.Int16 Then
719                Return CDbl(DirectCast(value, Global.System.Int16))
720            ElseIf TypeOf value Is Global.System.UInt16 Then
721                Return CDbl(DirectCast(value, Global.System.UInt16))
722            ElseIf TypeOf value Is Global.System.Int32 Then
723                Return CDbl(DirectCast(value, Global.System.Int32))
724            ElseIf TypeOf value Is Global.System.UInt32 Then
725                Return CDbl(DirectCast(value, Global.System.UInt32))
726            ElseIf TypeOf value Is Global.System.Int64 Then
727                Return CDbl(DirectCast(value, Global.System.Int64))
728            ElseIf TypeOf value Is Global.System.UInt64 Then
729                Return CDbl(DirectCast(value, Global.System.UInt64))
730            ElseIf TypeOf value Is Decimal Then
731                Return CDbl(DirectCast(value, Global.System.Decimal))
732            ElseIf TypeOf value Is Single Then
733                Return CDbl(DirectCast(value, Single))
734            ElseIf TypeOf value Is Double Then
735                Return CDbl(DirectCast(value, Double))
736            ElseIf TypeOf value Is String Then
737                Return CDbl(DirectCast(value, String))
738            End If
739            Throw New Global.System.InvalidCastException()
740        End Function
741        Private Shared Function ParseDouble(value As String) As Double
742            Dim normalizedNumberFormat As Global.System.Globalization.NumberFormatInfo
743            Dim culture As Global.System.Globalization.CultureInfo = GetCultureInfo()
744            Dim numberFormat As Global.System.Globalization.NumberFormatInfo = culture.NumberFormat
745            normalizedNumberFormat = GetNormalizedNumberFormat(numberFormat)
746            Const flags As Global.System.Globalization.NumberStyles =
747                    Global.System.Globalization.NumberStyles.AllowDecimalPoint Or
748                    Global.System.Globalization.NumberStyles.AllowExponent Or
749                    Global.System.Globalization.NumberStyles.AllowLeadingSign Or
750                    Global.System.Globalization.NumberStyles.AllowLeadingWhite Or
751                    Global.System.Globalization.NumberStyles.AllowThousands Or
752                    Global.System.Globalization.NumberStyles.AllowTrailingSign Or
753                    Global.System.Globalization.NumberStyles.AllowParentheses Or
754                    Global.System.Globalization.NumberStyles.AllowTrailingWhite Or
755                    Global.System.Globalization.NumberStyles.AllowCurrencySymbol
756            value = ToHalfwidthNumbers(value, culture)
757            Try
758                Return Global.System.Double.Parse(value, flags, normalizedNumberFormat)
759            Catch formatEx As Global.System.FormatException When Not (numberFormat Is normalizedNumberFormat)
760                Return Global.System.Double.Parse(value, flags, numberFormat)
761            Catch ex As Global.System.Exception
762                Throw ex
763            End Try
764        End Function
765        Public Shared Function ToDate(value As String) As Date
766            Dim parsedDate As Global.System.DateTime
767            Const parseStyle As Global.System.Globalization.DateTimeStyles =
768                Global.System.Globalization.DateTimeStyles.AllowWhiteSpaces Or
769                Global.System.Globalization.DateTimeStyles.NoCurrentDateDefault
770            Dim culture As Global.System.Globalization.CultureInfo = GetCultureInfo()
771            Dim result As Boolean = Global.System.DateTime.TryParse(ToHalfwidthNumbers(value, culture), culture, parseStyle, parsedDate)
772            If result Then
773                Return parsedDate
774            Else
775                Throw New Global.System.InvalidCastException()
776            End If
777        End Function
778        Public Shared Function ToDate(value As Object) As Date
779            If value Is Nothing Then
780                Return Nothing
781            End If
782            If TypeOf value Is Global.System.DateTime Then
783                Return CDate(DirectCast(value, Global.System.DateTime))
784            ElseIf TypeOf value Is String Then
785                Return CDate(DirectCast(value, String))
786            End If
787            Throw New Global.System.InvalidCastException()
788        End Function
789        Public Shared Function ToChar(value As String) As Char
790            If (value Is Nothing) OrElse (value.Length = 0) Then
791                Return Global.System.Convert.ToChar(0 And &HFFFFI)
792            End If
793            Return value.Chars(0)
794        End Function
795        Public Shared Function ToChar(value As Object) As Char
796            If value Is Nothing Then
797                Return Global.System.Convert.ToChar(0 And &HFFFFI)
798            End If
799            If TypeOf value Is Char Then
800                Return CChar(DirectCast(value, Char))
801            ElseIf TypeOf value Is String Then
802                Return CChar(DirectCast(value, String))
803            End If
804            Throw New Global.System.InvalidCastException()
805        End Function
806        Public Shared Function ToCharArrayRankOne(value As String) As Char()
807            If value Is Nothing Then
808                value = ""
809            End If
810            Return value.ToCharArray()
811        End Function
812        Public Shared Function ToCharArrayRankOne(value As Object) As Char()
813            If value Is Nothing Then
814                Return "".ToCharArray()
815            End If
816            Dim arrayValue As Char() = TryCast(value, Char())
817            If arrayValue IsNot Nothing AndAlso arrayValue.Rank = 1 Then
818                Return arrayValue
819            ElseIf TypeOf value Is String Then
820                Return DirectCast(value, String).ToCharArray()
821            End If
822            Throw New Global.System.InvalidCastException()
823        End Function
824        Public Shared Shadows Function ToString(value As Short) As String
825            Return value.ToString()
826        End Function
827        Public Shared Shadows Function ToString(value As Integer) As String
828            Return value.ToString()
829        End Function
830        <Global.System.CLSCompliant(False)>
831        Public Shared Shadows Function ToString(value As UInteger) As String
832            Return value.ToString()
833        End Function
834        Public Shared Shadows Function ToString(value As Long) As String
835            Return value.ToString()
836        End Function
837        <Global.System.CLSCompliant(False)>
838        Public Shared Shadows Function ToString(value As ULong) As String
839            Return value.ToString()
840        End Function
841        Public Shared Shadows Function ToString(value As Single) As String
842            Return value.ToString()
843        End Function
844        Public Shared Shadows Function ToString(value As Double) As String
845            Return value.ToString("G")
846        End Function
847        Public Shared Shadows Function ToString(value As Date) As String
848            Dim timeTicks As Long = value.TimeOfDay.Ticks
849            If (timeTicks = value.Ticks) OrElse
850                (value.Year = 1899 AndAlso value.Month = 12 AndAlso value.Day = 30) Then
851                Return value.ToString("T")
852            ElseIf timeTicks = 0 Then
853                Return value.ToString("d")
854            Else
855                Return value.ToString("G")
856            End If
857        End Function
858        Public Shared Shadows Function ToString(value As Decimal) As String
859            Return value.ToString("G")
860        End Function
861        Public Shared Shadows Function ToString(value As Object) As String
862            If value Is Nothing Then
863                Return Nothing
864            Else
865                Dim stringValue As String = TryCast(value, String)
866                If stringValue IsNot Nothing Then
867                    Return stringValue
868                End If
869            End If
870            If TypeOf value Is Global.System.Enum Then
871                value = GetEnumValue(value)
872            End If
873            If TypeOf value Is Boolean Then
874                Return CStr(DirectCast(value, Boolean))
875            ElseIf TypeOf value Is SByte Then
876                Return CStr(DirectCast(value, SByte))
877            ElseIf TypeOf value Is Byte Then
878                Return CStr(DirectCast(value, Byte))
879            ElseIf TypeOf value Is Global.System.Int16 Then
880                Return CStr(DirectCast(value, Global.System.Int16))
881            ElseIf TypeOf value Is Global.System.UInt16 Then
882                Return CStr(DirectCast(value, Global.System.UInt16))
883            ElseIf TypeOf value Is Global.System.Int32 Then
884                Return CStr(DirectCast(value, Global.System.Int32))
885            ElseIf TypeOf value Is Global.System.UInt32 Then
886                Return CStr(DirectCast(value, Global.System.UInt32))
887            ElseIf TypeOf value Is Global.System.Int64 Then
888                Return CStr(DirectCast(value, Global.System.Int64))
889            ElseIf TypeOf value Is Global.System.UInt64 Then
890                Return CStr(DirectCast(value, Global.System.UInt64))
891            ElseIf TypeOf value Is Decimal Then
892                Return CStr(DirectCast(value, Global.System.Decimal))
893            ElseIf TypeOf value Is Single Then
894                Return CStr(DirectCast(value, Single))
895            ElseIf TypeOf value Is Double Then
896                Return CStr(DirectCast(value, Double))
897            ElseIf TypeOf value Is Char Then
898                Return CStr(DirectCast(value, Char))
899            ElseIf TypeOf value Is Date Then
900                Return CStr(DirectCast(value, Date))
901            Else
902                Dim charArray As Char() = TryCast(value, Char())
903                If charArray IsNot Nothing Then
904                    Return New String(charArray)
905                End If
906            End If
907            Throw New Global.System.InvalidCastException()
908        End Function
909        Public Shared Shadows Function ToString(value As Boolean) As String
910            If value Then
911                Return Global.System.Boolean.TrueString
912            Else
913                Return Global.System.Boolean.FalseString
914            End If
915        End Function
916        Public Shared Shadows Function ToString(value As Byte) As String
917            Return value.ToString()
918        End Function
919        Public Shared Shadows Function ToString(value As Char) As String
920            Return value.ToString()
921        End Function
922        Public Shared Function GetCultureInfo() As Global.System.Globalization.CultureInfo
923            Return Global.System.Globalization.CultureInfo.CurrentCulture
924        End Function
925        Public Shared Function ToHalfwidthNumbers(s As String, culture As Global.System.Globalization.CultureInfo) As String
926            Return s
927        End Function
928        Public Shared Function IsHexOrOctValue(value As String, ByRef i64Value As Global.System.Int64) As Boolean
929            Dim ch As Char
930            Dim length As Integer
931            Dim firstNonspace As Integer
932            Dim tmpValue As String
933            length = value.Length
934            Do While (firstNonspace < length)
935                ch = value.Chars(firstNonspace)
936                If ch = "&"c AndAlso firstNonspace + 2 < length Then
937                    GoTo GetSpecialValue
938                End If
939                If ch <> Strings.ChrW(32) AndAlso ch <> Strings.ChrW(&H3000) Then
940                    Return False
941                End If
942                firstNonspace += 1
943            Loop
944            Return False
945GetSpecialValue:
946            ch = Global.System.Char.ToLowerInvariant(value.Chars(firstNonspace + 1))
947            tmpValue = ToHalfwidthNumbers(value.Substring(firstNonspace + 2), GetCultureInfo())
948            If ch = "h"c Then
949                i64Value = Global.System.Convert.ToInt64(tmpValue, 16)
950            ElseIf ch = "o"c Then
951                i64Value = Global.System.Convert.ToInt64(tmpValue, 8)
952            Else
953                Throw New Global.System.FormatException
954            End If
955            Return True
956        End Function
957        <Global.System.CLSCompliant(False)>
958        Public Shared Function IsHexOrOctValue(value As String, ByRef ui64Value As Global.System.UInt64) As Boolean
959            Dim ch As Char
960            Dim length As Integer
961            Dim firstNonspace As Integer
962            Dim tmpValue As String
963            length = value.Length
964            Do While (firstNonspace < length)
965                ch = value.Chars(firstNonspace)
966                If ch = "&"c AndAlso firstNonspace + 2 < length Then
967                    GoTo GetSpecialValue
968                End If
969                If ch <> Strings.ChrW(32) AndAlso ch <> Strings.ChrW(&H3000) Then
970                    Return False
971                End If
972                firstNonspace += 1
973            Loop
974            Return False
975GetSpecialValue:
976            ch = Global.System.Char.ToLowerInvariant(value.Chars(firstNonspace + 1))
977            tmpValue = ToHalfwidthNumbers(value.Substring(firstNonspace + 2), GetCultureInfo())
978            If ch = "h"c Then
979                ui64Value = Global.System.Convert.ToUInt64(tmpValue, 16)
980            ElseIf ch = "o"c Then
981                ui64Value = Global.System.Convert.ToUInt64(tmpValue, 8)
982            Else
983                Throw New Global.System.FormatException
984            End If
985            Return True
986        End Function
987        Public Shared Function ToGenericParameter(Of T)(value As Object) As T
988            If value Is Nothing Then
989                Return Nothing
990            End If
991            Dim reflectedType As Global.System.Type = GetType(T)
992            If Global.System.Type.Equals(reflectedType, GetType(Global.System.Boolean)) Then
993                Return DirectCast(CObj(CBool(value)), T)
994            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.SByte)) Then
995                Return DirectCast(CObj(CSByte(value)), T)
996            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Byte)) Then
997                Return DirectCast(CObj(CByte(value)), T)
998            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Int16)) Then
999                Return DirectCast(CObj(CShort(value)), T)
1000            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.UInt16)) Then
1001                Return DirectCast(CObj(CUShort(value)), T)
1002            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Int32)) Then
1003                Return DirectCast(CObj(CInt(value)), T)
1004            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.UInt32)) Then
1005                Return DirectCast(CObj(CUInt(value)), T)
1006            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Int64)) Then
1007                Return DirectCast(CObj(CLng(value)), T)
1008            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.UInt64)) Then
1009                Return DirectCast(CObj(CULng(value)), T)
1010            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Decimal)) Then
1011                Return DirectCast(CObj(CDec(value)), T)
1012            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Single)) Then
1013                Return DirectCast(CObj(CSng(value)), T)
1014            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Double)) Then
1015                Return DirectCast(CObj(CDbl(value)), T)
1016            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.DateTime)) Then
1017                Return DirectCast(CObj(CDate(value)), T)
1018            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.Char)) Then
1019                Return DirectCast(CObj(CChar(value)), T)
1020            ElseIf Global.System.Type.Equals(reflectedType, GetType(Global.System.String)) Then
1021                Return DirectCast(CObj(CStr(value)), T)
1022            Else
1023                Return DirectCast(value, T)
1024            End If
1025        End Function
1026
1027        Private Shared Function CastSByteEnum(ByVal expression As SByte, ByVal targetType As Type) As Object
1028            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1029            Return expression
1030        End Function
1031
1032        Private Shared Function CastByteEnum(ByVal expression As Byte, ByVal targetType As Type) As Object
1033            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1034            Return expression
1035        End Function
1036
1037        Private Shared Function CastInt16Enum(ByVal expression As Int16, ByVal targetType As Type) As Object
1038            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1039            Return expression
1040        End Function
1041
1042        Private Shared Function CastUInt16Enum(ByVal expression As UInt16, ByVal targetType As Type) As Object
1043            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1044            Return expression
1045        End Function
1046
1047        Private Shared Function CastInt32Enum(ByVal expression As Int32, ByVal targetType As Type) As Object
1048            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1049            Return expression
1050        End Function
1051
1052        Private Shared Function CastUInt32Enum(ByVal expression As UInt32, ByVal targetType As Type) As Object
1053            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1054            Return expression
1055        End Function
1056
1057        Private Shared Function CastInt64Enum(ByVal expression As Int64, ByVal targetType As Type) As Object
1058            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1059            Return expression
1060        End Function
1061
1062        Private Shared Function CastUInt64Enum(ByVal expression As UInt64, ByVal targetType As Type) As Object
1063            If IsEnum(targetType) Then Return System.Enum.ToObject(targetType, expression)
1064            Return expression
1065        End Function
1066
1067        Friend Shared Function ForceValueCopy(ByVal expression As Object, ByVal targetType As Type) As Object
1068            'Is there any way to get this faster?  It's called every time we pass a valuetype to a byref parameter.
1069
1070            If expression Is Nothing Then
1071                Return expression
1072            End If
1073
1074            Dim tyCode As TypeCode = expression.GetType().GetTypeCode
1075
1076            Debug.Assert(tyCode = GetTypeCode(targetType), "expected types to match")
1077
1078            Select Case tyCode
1079
1080                Case TypeCode.Boolean
1081                    Return Convert.ToBoolean(expression)
1082                Case TypeCode.SByte
1083                    Return CastSByteEnum(Convert.ToSByte(expression), targetType)
1084                Case TypeCode.Byte
1085                    Return CastByteEnum(Convert.ToByte(expression), targetType)
1086                Case TypeCode.Int16
1087                    Return CastInt16Enum(Convert.ToInt16(expression), targetType)
1088                Case TypeCode.UInt16
1089                    Return CastUInt16Enum(Convert.ToUInt16(expression), targetType)
1090                Case TypeCode.Int32
1091                    Return CastInt32Enum(Convert.ToInt32(expression), targetType)
1092                Case TypeCode.UInt32
1093                    Return CastUInt32Enum(Convert.ToUInt32(expression), targetType)
1094                Case TypeCode.Int64
1095                    Return CastInt64Enum(Convert.ToInt64(expression), targetType)
1096                Case TypeCode.UInt64
1097                    Return CastUInt64Enum(Convert.ToUInt64(expression), targetType)
1098                Case TypeCode.Decimal
1099                    Return Convert.ToDecimal(expression)
1100                Case TypeCode.Single
1101                    Return Convert.ToSingle(expression)
1102                Case TypeCode.Double
1103                    Return Convert.ToDouble(expression)
1104                Case TypeCode.DateTime
1105                    Return Convert.ToDateTime(expression)
1106                Case TypeCode.Char
1107                    Return Convert.ToChar(expression)
1108
1109                Case TypeCode.Empty
1110                    Debug.Assert(False, "shouldn't reach here")
1111
1112                Case TypeCode.Object,
1113                     TypeCode.String
1114
1115                    'fall through
1116            End Select
1117
1118            Return expression
1119        End Function
1120
1121        Private Shared Function ChangeIntrinsicType(ByVal expression As Object, ByVal targetType As Type) As Object
1122
1123            'This function will not handle user-defined conversion resolution, and so handles
1124            'only conversions between intrinsic types.
1125            Debug.Assert(IsIntrinsicType(expression.GetType) OrElse IsEnum(expression.GetType), "this function converts between intrinsic types only")
1126
1127            Select Case GetTypeCode(targetType)
1128
1129                Case TypeCode.Boolean : Return CBool(expression)
1130                Case TypeCode.SByte : Return CastSByteEnum(CSByte(expression), targetType)
1131                Case TypeCode.Byte : Return CastByteEnum(CByte(expression), targetType)
1132                Case TypeCode.Int16 : Return CastInt16Enum(CShort(expression), targetType)
1133                Case TypeCode.UInt16 : Return CastUInt16Enum(CUShort(expression), targetType)
1134                Case TypeCode.Int32 : Return CastInt32Enum(CInt(expression), targetType)
1135                Case TypeCode.UInt32 : Return CastUInt32Enum(CUInt(expression), targetType)
1136                Case TypeCode.Int64 : Return CastInt64Enum(CLng(expression), targetType)
1137                Case TypeCode.UInt64 : Return CastUInt64Enum(CULng(expression), targetType)
1138                Case TypeCode.Decimal : Return CDec(expression)
1139                Case TypeCode.Single : Return CSng(expression)
1140                Case TypeCode.Double : Return CDbl(expression)
1141                Case TypeCode.DateTime : Return CDate(expression)
1142                Case TypeCode.Char : Return CChar(expression)
1143                Case TypeCode.String : Return CStr(expression)
1144
1145                Case TypeCode.Empty,
1146                     TypeCode.Object
1147                    'fall through to error
1148            End Select
1149            Debug.Assert(False, "Expected intrinsic type only, not: " & targetType.Name)
1150            Throw New Exception  'would be nice to have an internal runtime exception or something like that
1151
1152        End Function
1153
1154
1155        Public Shared Function ChangeType(ByVal expression As Object, ByVal targetType As System.Type) As Object
1156            Return ChangeType(expression, targetType, False)
1157        End Function
1158
1159
1160        Friend Shared Function ChangeType(ByVal expression As Object, ByVal targetType As System.Type, ByVal dynamic As Boolean) As Object
1161            If targetType Is Nothing Then
1162                Throw New ArgumentException(GetResourceString(SR.Argument_InvalidNullValue1, "TargetType"))
1163            End If
1164
1165            If expression Is Nothing Then
1166                If IsValueType(targetType) Then
1167                    'method.invoke will do this for us, so when casting arguments to param types during
1168                    'latebinding, the createinstance call isn't needed, but ChangeType used in a generalized
1169                    'manner should return a default instance.
1170                    Return Activator.CreateInstance(targetType)
1171                Else
1172                    Return Nothing
1173                End If
1174            End If
1175
1176            Dim sourceType As Type = expression.GetType
1177            Debug.Assert(Not sourceType.IsByRef, "never expected to see byref source type")
1178
1179            'Dig through ByRef types which might come in.
1180            If targetType.IsByRef Then targetType = targetType.GetElementType
1181
1182            If targetType Is sourceType OrElse IsRootObjectType(targetType) Then
1183                Return expression
1184            End If
1185
1186            Dim targetTypeCode As TypeCode = GetTypeCode(targetType)
1187
1188            'All conversions between intrinsic types are natively built-in
1189            'and require no user-defined conversion resolution.
1190            If IsIntrinsicType(targetTypeCode) Then
1191                Dim sourceTypeCode As TypeCode = GetTypeCode(sourceType)
1192                If IsIntrinsicType(sourceTypeCode) Then
1193                    Return ChangeIntrinsicType(expression, targetType)
1194                End If
1195            End If
1196
1197            If targetType.IsInstanceOfType(expression) Then
1198                Return expression
1199            End If
1200
1201            If IsCharArrayRankOne(targetType) AndAlso IsStringType(sourceType) Then
1202                Return CType(DirectCast(expression, String), Char())
1203            End If
1204            If IsStringType(targetType) AndAlso IsCharArrayRankOne(sourceType) Then
1205                Return CStr(DirectCast(expression, Char()))
1206            End If
1207
1208            Debug.Assert(ClassifyPredefinedConversion(targetType, sourceType) = ConversionClass.None OrElse
1209                         ClassifyPredefinedConversion(targetType, sourceType) = ConversionClass.Narrowing,
1210                         "expected all predefined conversions handled by this point")
1211
1212            If dynamic Then
1213                Dim idmop As System.Dynamic.IDynamicMetaObjectProvider = IDOUtils.TryCastToIDMOP(expression)
1214                If idmop IsNot Nothing Then
1215                    Return IDOBinder.UserDefinedConversion(idmop, targetType)
1216                End If
1217            End If
1218            Return ObjectUserDefinedConversion(expression, targetType)
1219        End Function
1220
1221        <ObsoleteAttribute("do not use this method", True)>
1222        <DebuggerHiddenAttribute()> <DebuggerStepThroughAttribute()>
1223        Public Shared Function FallbackUserDefinedConversion(
1224                ByVal expression As Object, ByVal targetType As Type) As Object
1225
1226            Return ObjectUserDefinedConversion(expression, targetType)
1227        End Function
1228
1229        <DebuggerHiddenAttribute()> <DebuggerStepThroughAttribute()>
1230        Private Shared Function ObjectUserDefinedConversion(
1231                ByVal expression As Object, ByVal targetType As Type) As Object
1232
1233            Dim sourceType As Type = expression.GetType
1234            If ClassifyPredefinedConversion(targetType, sourceType) = ConversionClass.None AndAlso
1235               (IsClassOrValueType(sourceType) OrElse IsClassOrValueType(targetType)) AndAlso
1236               Not (IsIntrinsicType(sourceType) AndAlso IsIntrinsicType(targetType)) Then
1237
1238                'Conversions of the form S-->T use only one user-defined conversion at a time, i.e.,
1239                'user-defined conversions are not chained together.  It may be necessary to convert to and
1240                'from intermediate types using predefined conversions to match the signature of the
1241                'user-defined conversion exactly, so the conversion "path" is comprised of at most three
1242                'parts:
1243                '
1244                '    1) [ predefined conversion  S-->Sx ]
1245                '    2) User-defined conversion Sx-->Tx
1246                '    3) [ predefined conversion Tx-->T  ]
1247                '
1248                '    Where Sx is the intermediate source type
1249                '      and Tx is the intermediate target type
1250                '
1251                '    Steps 1 and 3 are optional given S == Sx or Tx == T.
1252                '
1253                'Given the source operand and target type, resolve the conversion operator and invoke it.
1254                'When invoking the conversion operator, the conversion from S-->Sx is done when matching
1255                'the arguments.  After invocation, we must handle the conversion from the result of the
1256                'invocation to the target type, i.e., Tx-->T.
1257
1258                'Resolve the operator.
1259                Dim operatorMethod As Method = Nothing
1260                Dim result As ConversionClass =
1261                    ClassifyUserDefinedConversion(targetType, sourceType, operatorMethod)
1262
1263                If operatorMethod IsNot Nothing Then
1264                    Debug.Assert(result = ConversionClass.Widening OrElse result = ConversionClass.Narrowing,
1265                                 "operator method not expected for invalid conversion")
1266
1267                    'Invoke the operator. This handles the conversion S-->Sx.
1268                    Dim baseReference As Container = New Container(operatorMethod.DeclaringType)
1269                    Dim invocationResult As Object =
1270                        baseReference.InvokeMethod(
1271                            operatorMethod,
1272                            New Object() {expression},
1273                            Nothing,
1274                            BindingFlagsInvokeMethod)
1275
1276                    'Now convert the result of the invocation to the target type, Tx-->T.
1277
1278#If DEBUG Then
1279                    If invocationResult IsNot Nothing Then
1280
1281
1282                        'Disabling the assert below when we're converting to Nullable(Of T)
1283                        'since the Runtime hasn't been updated yet to handle Nullable.  In this case the assert
1284                        'is harmless, but ClassifyPredefinedConversion hasn't been updated to consider Nullable conversions,
1285                        'and updating this across the entire runtime would be significant feature work.
1286
1287                        If Not (targetType.IsGenericType AndAlso
1288                                Not targetType.IsGenericTypeDefinition AndAlso
1289                                targetType.GetGenericTypeDefinition().Equals(GetType(Nullable(Of ))) AndAlso
1290                                targetType.GetGenericArguments().Length > 0 AndAlso
1291                                invocationResult.GetType().Equals(targetType.GetGenericArguments()(0))) Then
1292
1293
1294                            Dim PostConversion As ConversionClass = ClassifyPredefinedConversion(targetType, invocationResult.GetType)
1295
1296                            Debug.Assert(
1297                                PostConversion = ConversionClass.Narrowing OrElse
1298                                PostConversion = ConversionClass.Identity OrElse
1299                                PostConversion = ConversionClass.Widening,
1300                                "User defined conversion returned unexpected result")
1301                        End If
1302                    End If
1303#End If
1304                    Return ChangeType(invocationResult, targetType)
1305
1306                ElseIf result = ConversionClass.Ambiguous Then
1307                    Throw New InvalidCastException(
1308                        GetResourceString(
1309                            SR.AmbiguousCast2,
1310                            VBFriendlyName(sourceType),
1311                            VBFriendlyName(targetType)))
1312                End If
1313
1314            End If
1315
1316            Throw New InvalidCastException(
1317                GetResourceString(
1318                    SR.InvalidCast_FromTo,
1319                    VBFriendlyName(sourceType),
1320                    VBFriendlyName(targetType)))
1321
1322        End Function
1323
1324        ' Simplied version of ObjectUserDefinedConversion, above
1325        ' Determines if conversion is possible
1326        Friend Shared Function CanUserDefinedConvert(ByVal expression As Object, ByVal targetType As Type) As Boolean
1327
1328            Dim sourceType As Type = expression.GetType
1329            If ClassifyPredefinedConversion(targetType, sourceType) = ConversionClass.None AndAlso
1330               (IsClassOrValueType(sourceType) OrElse IsClassOrValueType(targetType)) AndAlso
1331               Not (IsIntrinsicType(sourceType) AndAlso IsIntrinsicType(targetType)) Then
1332
1333                'Resolve the operator.
1334                Dim operatorMethod As Method = Nothing
1335                Dim result As ConversionClass =
1336                    ClassifyUserDefinedConversion(targetType, sourceType, operatorMethod)
1337
1338                Return operatorMethod IsNot Nothing
1339            End If
1340
1341            Return False
1342        End Function
1343
1344    End Class
1345End Namespace
1346