0

I am trying to assign a value to global variable, which has a Property of type Double. This Property is passed as Object and the assignment fails.

In the example code below, the value is never assigned to the actual object, but only locally:

Public Class Form1
    Friend Home As New Building

    Private Sub AssignValues() Handles Me.Load
        'Objects of different types are added to a list
        Dim listObjects As New List(Of Object)
        listObjects.Add(Home.Surface)

        'All the Objects in listObjects are assigned a value that
        'is stored as String
        For Each o As Object In listObjects
            SetProperty(o, "45.6")
            Debug.Print("Surface = " & Home.Surface.ToString)
        Next
    End Sub

    Private Sub SetProperty(ByRef Variable As Object, ByVal Value As String)
        Select Case Variable.GetType
            Case GetType(Double)
                Variable = CDbl(Value)
            Case Else
                '...
        End Select
    End Sub
End Class

Public Class Building
    Dim _surface As Double = 0
    Public Property Surface As Double
        Get
            Return _surface
        End Get
        Set(ByVal value As Double)
            _surface = value
        End Set
    End Property
End Class

The program invariably outputs Surface = 0 instead of 45.6. What am I doing wrong?

I tried to pass the Variable as reference, as suggested here, but without success. I also read about using Reflection, but there ought to be something simpler than that...

Community
  • 1
  • 1
Nicolas
  • 1,151
  • 3
  • 15
  • 28

2 Answers2

2

When your adding home.surface to the list, your adding a copy of the double to the list and then adjusting that copy. Stick a watch on "o" and see how it changes whilst home.surface remains the same.

If you want to use reflection, try something along these lines.

Dim prop As Reflection.PropertyInfo = o.GetType().GetProperty("Surface")
prop.SetValue(o, 45.6)
Jay Zelos
  • 1,409
  • 1
  • 9
  • 10
  • Wouldn't it be possible not add a copy of the double to my list, but the double itself, or a reference to it? – Nicolas Jul 03 '13 at 12:58
  • 1
    You could add a reference to "Home" but as far as I'm aware you cannot add a reference to a value type. – Jay Zelos Jul 03 '13 at 13:12
  • Ok, so I either have to use reflection or to change the structure of the objects I'm passing so that they are not value types any more. I think I'll try the second option first. Thanks for the help! – Nicolas Jul 03 '13 at 14:35
1

With Variable.GetType you will get always Object, because this is the type of Variable. What you can do with an Object is converting/casting it into a different type (like Double).

The best way to determine the "original type" from where the Object comes would be including an additional variable telling it. Another option might be converting the given Object into the target Type and see if it is not nothing/does not trigger an error. But this second option is not too accurate, mainly when dealing with "equivalent types" like Doubles/Integers.

varocarbas
  • 12,354
  • 4
  • 26
  • 37
  • That seems actually not to be true. When I run the code above, the `Case GetType(Double)` is entered. – Nicolas Jul 03 '13 at 13:47
  • 1
    Originally, I tested it with VS 2008 and it was impossible to even compile the project. Right now I am testing it with VS 2010 and you are right!? I don't know what to say; this is not the logical/expected/ideal behaviour but seems to work fine on this specific context. But also it is not clear why the property is not set rightly. What is clear is that object = CDbl(Value) cannot be right you have to do object = value and then convert object to double. By doing this in VS 2010, I get the right value for o (25.4), with your code I get 254. – varocarbas Jul 03 '13 at 13:55
  • PS: I can delete my answer if you wish. But independently upon what VB does internally, theoretically your code is doing something wrong; if you don't get an error is because VB (in VS 2010, not before) corrects it automatically. – varocarbas Jul 03 '13 at 13:57
  • I find it actually really interesting to learn that this code does not work under VS2008. I am, yes, using VS2010. And you're right also that the `CDbl()` actually converts the value from `45.6` to `456`. And no error or warning is displayed, even with ' Option Explicit On`. Only one thing here is sure: I can't keep that code :-) – Nicolas Jul 03 '13 at 14:43
  • Better doing things right rather than expecting VB to correct problems. VB over-corrects much more than other languages and this is certainly nice although might become a bit dangerous some times. Anyway... happy to have been of some help. – varocarbas Jul 03 '13 at 14:55