Results 1 to 4 of 4

Thread: [RESOLVED] [2005] items values changing in list when new item added

  1. #1

    Thread Starter
    Frenzied Member vbdotnetboy's Avatar
    Join Date
    Jun 2004
    Location
    Lewisburg, PA "Next year Raiders in the Super Bowl"
    Posts
    1,310

    Resolved [RESOLVED] [2005] items values changing in list when new item added

    Description:
    First the explaination of a I have a function that I’ve created. It basically uses reflection to create and return a particular type. Whatever I pass in is what I will get back and the function is complete generic. Heres my two senrios. I also use a class called SafeDataReader, which all it does is simple implement the IDataReader interface and does some behind the scenes things so as to not return a DBNull.Value, if that’s what was returned from the read, but the value you except ie you want a string you get an empty string not a DBNul value. Ok here we go, if I don’t make any sense let me know.

    1. I have a class call Abc. It has a property called Name. The constructor is like so… Public Sub New(ByVal dr As SafeDataReader)
    2. Now I have a class called AbcXyzManager that inherits from a base class that I’ve created and has a function with the following signature. Protected Function FetchDataObjects(Of T, C As List(Of T))(ByVal objectToCreate As Type, ByVal sqlStatement As String, ByVal params As Core.CSSIDbParameterCollection, Optional ByVal cmdType As CommandType = CommendType.Text) As C
    3. Now in a function in the AbcXyzManager class called GetAbcList I setup the sql statement and parameters this function is going to return a List(Of Abc). So the signature of the inherited function would look like so Return FetchDataObjects(Of Abc, List(Of Abc))(GetType(Abc), sql, params).
    4. What the code below runs it returns a list of Abc that has 3 items each item has different values.
    5. This all works just fine item 1’s Abc.Name = Test1, 2’s Abc.Name = Test2, and 3’s Abc.Name = Test3.
    6. Now for the kicker.
    7. I do the same exact thing only this time I have a class called Xyz, might have different properties, but the same type of constructor.
    8. In the AbcXyzManager I have a function called GetXyzList again I setup everything and then return a List of type Xyz.
    9. Again I use the FetchDataObjects the only difference this time is it’s of type Xyz and the list is of type Xyz. So the object that needs to be created is Xyz.
    10. When the code runs and reads data creates an instance of Xyz and adds it to the list, everything works fine… Until it reads the next record.
    11. When it reads the record, instanciates the Xyz object and calls the constructor everything works as it should. I read the records and setup whatever properties/members need to be in the Xyz object.
    12. Now for the real big kicker… Once the newly created object is added to the list. If I look at the list so far only two Xyz objects have been added… you would think that these two items of xyz would have different values for the properties… ie lets say there are two properties Name and Number. Name should be Test1, Number should be 1, because that’s what was read from the first record. Now the second item should have a Name property value of Test2 and a Number property value of 2, because again that’s what was read from the second record. However, if I look at the first item the Name value is Test2 and the Number value is 2. It’s as though it’s over writing the previous item(s).

    I’ve stepped through my code and watched each and ever value be set each time a record was read. Each time the values are different and prior to adding the newly created Xyz object to the list the first item has different values. As soon as the new Xyz object is added to the list thouh all previous items in the list take on the values from that Xyz object. Again I use the same code for creating a list of type Abc and it works perfectly fine. Here’s the code of the base class function. The problem occurs when it runs the following code.

    vb Code:
    1. Do While dr.Read
    2.     retval.Add(Activator.CreateInstance(objectToCreate, New Object() {dr}))
    3. Loop







    vb Code:
    1. Protected Function FetchDataObjects(Of T, C As List(Of T))(ByVal objectToCreate As Type, _
    2.                                             ByVal sqlStatement As String, _
    3.                                             ByVal params As DbParameter(), _
    4.                                             Optional ByVal cmdType As CommandType = CommandType.Text) _
    5.                                             As C
    6.             Dim retval As List(Of T) = Nothing
    7.             Try
    8.                 m_Cnn = DbProviderFactories.GetFactory(m_Provider).CreateConnection
    9.                 m_Cnn.ConnectionString = m_CnnStr
    10.                 m_Cnn.Open()
    11.                 If m_Cnn.State = ConnectionState.Open Then
    12.                     m_Cmd = m_Cnn.CreateCommand
    13.                     m_Cmd.CommandText = sqlStatement
    14.                     m_Cmd.CommandType = cmdType
    15.                     If params IsNot Nothing AndAlso params.Count > 0 Then
    16.                        m_Cmd.Parameters.AddRange(params)
    17.                     End If
    18.                     Try
    19.                         Using dr As New Data.Core.SafeDataReader(m_Cmd.ExecuteReader)
    20.                             Try
    21.                                 retval = New List(Of T)
    22.                                 Do While dr.Read
    23.                                     retval.Add(Activator.CreateInstance(objectToCreate, New Object() {dr}))
    24.                                 Loop
    25.                             Catch dbEx As DbException
    26.                                 Throw dbEx
    27.                             Catch ex As Exception
    28.                                 Throw ex
    29.                             End Try
    30.                         End Using
    31.                     Catch dbEx As DbException
    32.                         Throw dbEx
    33.                     Catch ex As Exception
    34.                         Throw ex
    35.                     End Try
    36.                 End If
    37.             Catch ex As Exception
    38.                 Throw ex
    39.             Finally
    40.                 If m_Adapter IsNot Nothing Then
    41.                     m_Adapter.Dispose()
    42.                     m_Adapter = Nothing
    43.                 End If
    44.                 If m_Cmd IsNot Nothing Then
    45.                     m_Cmd.Dispose()
    46.                     m_Cmd = Nothing
    47.                 End If
    48.                 If m_Cnn IsNot Nothing Then
    49.                     'Place closing in try block as the connection
    50.                     'object may still be disposed.
    51.                     Try
    52.                         m_Cnn.Close()
    53.                         m_Cnn.Dispose()
    54.                     Finally
    55.                         m_Cnn = Nothing
    56.                     End Try
    57.                 End If
    58.             End Try
    59.             Return retval
    60.         End Function

    Derek - Using VS 2008 99% of the time and VS 2003 1% of the time

    Please Help Us To Save Ana

    ● Helpful Links: DNR TV | Awesome site for tips | Using ADO.NET to work with Excel | Xml Namespace 2.0 Framework Changes|Ultra High Security Password Generator | Mendhak's ADO.NET Tutorial
    ● Code Bank: Random Password Generator | Generic DbProviderFactory Access
    ● Site Work: Bottle Run Xtreme | Spaids Racing.com

    Company I work for - CSSI

    WHEN POSTING PLEASE INDICATE VERSION

    Please use vbcode tags or code tags when posting code
    [highlight=vb]ALL your code goes here[/highlight] or [code]ALL your code goes here[/code]

    If my post helped you in anyway... please be kind and give me some ratings

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: [2005] items values changing in list when new item added

    The problem appears clear: Objects are never actually added to the list, all that is ever added is a reference to an object. In this case, what is being added is just copies of references to new objects, rather than references to new objects. You pointed out where the problem is occuring, and I managed to overlook that part and identify where the problem was occuring by looking at the code, so your previous statement matches up with what I was seeing. However, you don't show what is happening in that Add argument which is causing the trouble.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Frenzied Member vbdotnetboy's Avatar
    Join Date
    Jun 2004
    Location
    Lewisburg, PA "Next year Raiders in the Super Bowl"
    Posts
    1,310

    Re: [2005] items values changing in list when new item added

    sorry shaggy, i'm not i understand how i'm not showing what is happening in the add argument. unless you're talking about the Activator.CreateInstance. in either case here's something else that I tried. returned a datatable and looped through the rows creating a new instance of the object and adding it to a list. again same problem

    vb Code:
    1. Dim lst As New List(Of Xyz)
    2. For Each row In tbl.Rows
    3.     Dim obj As New Xyz(row(0), row(1), row(2))
    4.     lst.Add(obj)
    5. Next

    as soon as the second record is read, the object is create and added, the previous item in the list changes

    Derek - Using VS 2008 99% of the time and VS 2003 1% of the time

    Please Help Us To Save Ana

    ● Helpful Links: DNR TV | Awesome site for tips | Using ADO.NET to work with Excel | Xml Namespace 2.0 Framework Changes|Ultra High Security Password Generator | Mendhak's ADO.NET Tutorial
    ● Code Bank: Random Password Generator | Generic DbProviderFactory Access
    ● Site Work: Bottle Run Xtreme | Spaids Racing.com

    Company I work for - CSSI

    WHEN POSTING PLEASE INDICATE VERSION

    Please use vbcode tags or code tags when posting code
    [highlight=vb]ALL your code goes here[/highlight] or [code]ALL your code goes here[/code]

    If my post helped you in anyway... please be kind and give me some ratings

  4. #4

    Thread Starter
    Frenzied Member vbdotnetboy's Avatar
    Join Date
    Jun 2004
    Location
    Lewisburg, PA "Next year Raiders in the Super Bowl"
    Posts
    1,310

    Re: [2005] items values changing in list when new item added

    here's code i threw together quick that does basically the same thing only it's not reading from a database and i'm only adding 7 items. this works as it should

    vb Code:
    1. Module Module1
    2.  
    3.     Sub Main()
    4.         For Each itm As Test In Testing(Of Test, List(Of Test))(GetType(Test))
    5.             Console.WriteLine("{0} {1}", itm.Name, itm.Number)
    6.         Next
    7.         Console.Read()
    8.     End Sub
    9.  
    10.     Private Function Testing(Of T, C As List(Of T))(ByVal obj As Type) As C
    11.         Dim lst As New List(Of T)
    12.         For i As Integer = 1 To 7
    13.             lst.Add(Activator.CreateInstance(obj, New Object() {"test" + i.ToString, i}))
    14.         Next
    15.         Return lst
    16.     End Function
    17.  
    18. End Module
    19.  
    20.  
    21. Public Class Test
    22.     Private m_name As String
    23.     Private m_number As Int32
    24.  
    25.     Public Property Name() As String
    26.         Get
    27.             Return m_name
    28.         End Get
    29.         Set(ByVal value As String)
    30.             m_name = value
    31.         End Set
    32.     End Property
    33.  
    34.     Public Property Number() As Int32
    35.         Get
    36.             Return m_number
    37.         End Get
    38.         Set(ByVal value As Int32)
    39.             m_number = value
    40.         End Set
    41.     End Property
    42.  
    43.     Public Sub New(ByVal n1 As String, ByVal n2 As Int32)
    44.         m_name = n1
    45.         m_number = n2
    46.     End Sub
    47. End Class

    Derek - Using VS 2008 99% of the time and VS 2003 1% of the time

    Please Help Us To Save Ana

    ● Helpful Links: DNR TV | Awesome site for tips | Using ADO.NET to work with Excel | Xml Namespace 2.0 Framework Changes|Ultra High Security Password Generator | Mendhak's ADO.NET Tutorial
    ● Code Bank: Random Password Generator | Generic DbProviderFactory Access
    ● Site Work: Bottle Run Xtreme | Spaids Racing.com

    Company I work for - CSSI

    WHEN POSTING PLEASE INDICATE VERSION

    Please use vbcode tags or code tags when posting code
    [highlight=vb]ALL your code goes here[/highlight] or [code]ALL your code goes here[/code]

    If my post helped you in anyway... please be kind and give me some ratings

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width