(I removed all this part because it is not applicable anymore to the new text of the question)
--- SAMPLE CODE (original question)
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim Obj As Object
'Argument as Object treated as String
Obj = "converting into string although still is an object"
Dim outString As String = ObjToString(Obj)
'Is, complex behaviour; equals (=), always the same
Obj = "This one is 1"
Dim is1 As Integer = IsVsEqual(Obj, False) '1
Dim equal1 As Integer = IsVsEqual(Obj, True) '1
Obj = 1.0d 'This one 2
Dim outIndex2 As Integer = IsVsEqual(Obj, False) '2
Dim equal2 As Integer = IsVsEqual(Obj, True) '1
End Sub
Private Function ObjToString(obj As Object) As String
Dim nowIWantString As String = obj.ToString()
nowIWantString = nowIWantString & " -- now string 100%"
Return nowIWantString
End Function
Private Function IsVsEqual(obj As Object, tryEqual As Boolean) As Integer
Dim obj2 As Object = obj
Dim outIndex As Integer = 0
If (tryEqual) Then
If (obj2 = obj) Then
outIndex = 1
Else
outIndex = 2
End If
Else
If (obj2 Is obj) Then
outIndex = 1
Else
outIndex = 2
End If
End If
Return outIndex
End Function
End Class
--- ANSWER TO THE UPDATED QUESTION
I have to recognise that I am somehow impressed with the results you are showing. I haven't ever looked at all this in detail but the fact of having two different treatments for two different groups of types; and getting to the point of provoking ReferenceEquals(sameObject, sameObject) = False
is certainly curious. Just a quick summary of your example:
Dim O1 As Object = new Object
If Not Object.ReferenceEquals(O1, O1) Then
'This object will show the "quirky behaviour"
End If
Making an Object Type
variable going through this condition is as easy as doing O1 = 2D
. You have also observed that, in these cases, the WeakReference
has to be defined slightly different: wr = New WeakReference(CType(quirkyObj, ValueType))
.
All this is certainly interesting (more than what I thought before reading this last question :)), although can be avoided by relying on codes like this one (or the one above):
Public Function dealWithNumObjects(a As Object) As Object
Dim outObject As Object = a
If (TypeOf a Is Double) Then
'Do operations as double
ElseIf (TypeOf a Is Decimal) Then
'Do operations as decimal
ElseIf (TypeOf a Is Integer) Then
'Do operations as integer
End If
Return outObject
End Function
Which can be used like this:
Dim input As Object
input = 5D 'Decimal
Dim outputDecimal As Decimal = DirectCast(dealWithNumObjects(input), Decimal)
input = 5.0 'Double
Dim outputDouble As Double = DirectCast(dealWithNumObjects(input), Double)
input = 5 'Integer
Dim outputInteger As Integer = DirectCast(dealWithNumObjects(input), Integer)
This approach looks just at values and thus being quirky or not does not really matter (Decimal
is quirky but neither Double
nor Integer
and this method works fine with all of them).
In summary: before reading your example, I would have said: avoid problems and just use objects as "temporary holders of values", convert them into the target type ASAP and deal with the target type. After reading your answer, I do recognise that your methodology seems quite solid ("pretty ugly"? Why? I like the ReferenceEquals
approach but if you don't like it and just want to determine if the type is primitive you can rely on O1.GetType().IsPrimitive
) and might have some applicability. I cannot come up with a better way to do things than in your example: you are able to locate the "quirky" types and to keep a WeakReference. I guess that this is the maximum you can get under these conditions.