#.net #vb.net #reference #datarow #object-reference
#.net #vb.net #ссылка #поток данных #ссылка на объект
Вопрос:
Может ли кто-нибудь точно объяснить, почему метод 1 в следующем коде не изменяет DataTable там, где это делают другие 2 метода?
Очевидно, что это какая-то проблема со ссылками, но почему именно?
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. Хороший ответ. Я уже понял, как это работает, и я все еще думаю, что теперь я понимаю это лучше. 🙂