Объясните, почему этот поток данных не изменяется

#.net #vb.net #reference #datarow #object-reference

#.net #vb.net #ссылка #поток данных #ссылка на объект

Вопрос:

Может ли кто-нибудь точно объяснить, почему метод 1 в следующем коде не изменяет DataTable там, где это делают другие 2 метода?

Очевидно, что это какая-то проблема со ссылками, но почему именно?

КОД В IDEONE ЗДЕСЬ

 Imports System
Imports System.Data

Public Class Test

        Public Shared Sub Main()
                'Build Table
                Dim dt as New DataTable
                dt.Columns.Add("ID",GetType(String))
                dt.Columns.Add("Name",GetType(String))

                'Populate Table
                Dim dr as DataRow
                dr = dt.NewRow()
                dr("ID")="Man" : dr("Name") = "mike" : dt.Rows.Add(dr)
                dr = dt.NewRow()
                dr("ID")="Man" : dr("Name") = "ian" : dt.Rows.Add(dr)
                dr = dt.NewRow()
                dr("ID")="Man" : dr("Name") = "rob" : dt.Rows.Add(dr)
                dr = dt.NewRow()
                dr("ID")="Woman" : dr("Name") = "ann" : dt.Rows.Add(dr)
                dr = dt.NewRow()
                dr("ID")="Woman" : dr("Name") = "sam" : dt.Rows.Add(dr)

                output(dt)      'Output Table

                Dim drFilters() as DataRow = dt.Select("ID='Man'")      'Select all Man

                'Method 1 does not change dt
                'dr = dt.NewRow()
                'dr("ID")="cowman" : dr("Name")="bugle"
                'drFilters(1)=dr

                'Method 2 does change dt
                dr = drFilters(1)
                dr("ID")="cowman" : dr("Name")="bugle"

                'Method 3 does change dt
                'drFilters(1)("ID")="cowman" : drFilters(1)("Name")="bugle"

                output(dt)    'Output final table
        End Sub

        Public Shared Sub output(dt as DataTable)
                for each dr as DataRow in dt.Rows
                        Console.WriteLine(dr("ID")   vbTab   dr("Name"))
                Next
                Console.WriteLine("")
        End Sub

End Class
  

Извиняюсь за глупые тестовые данные 🙂

Ответ №1:

При вызове вы drFilters(1)=dr заменили DataRow ссылку в коллекции фильтров, которая является отдельной коллекцией от ссылок на строки в DataTable самой. dt.Rows это список ссылок на DataRow объекты, как есть drFilters() , но изменение записи в одном списке ссылок никоим образом не влияет на другой список ссылок.

 dt.Rows
0 => dt.Rows(0)
1 => dt.Rows(1)
2 => dt.Rows(2)
3 => dt.Rows(3)
4 => dt.Rows(4)

drFilter()
0 => dt.Rows(0)
1 => dt.Rows(1)
2 => dt.Rows(2)
  

После вызова drFilters(1)=dr коллекции выглядят следующим образом

 dt.Rows
0 => dt.Rows(0)
1 => dt.Rows(1)
2 => dt.Rows(2)
3 => dt.Rows(3)
4 => dt.Rows(4)

drFilter()
0 => dt.Rows(0)
1 => dr
2 => dt.Rows(2)
  

Обратите внимание, что dt.Rows это оставлено без изменений. Однако, когда вы извлекаете объект drFilters(1) и вносите в него изменения, у вас есть ссылка непосредственно на dt.Rows(1) , поэтому изменения в его свойствах отражаются в выходных dt данных .

Надеюсь, это поможет!

Комментарии:

1. Хороший ответ. Я уже понял, как это работает, и я все еще думаю, что теперь я понимаю это лучше. 🙂