变量指的是同一个实例

时间:2017-01-04 08:04:17

标签: vb.net list ienumerable

在我的学习曲线中,我会在彼此之间转换 String str = obj.getString("eventdate").replaceAll("\\D+", ""); String upToNCharacters = str.substring(0, Math.min(str.length(), 13)); DateFormat timeZoneFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); timeZoneFormat.setTimeZone(TimeZone.getTimeZone("GMT-8")); Date time = new java.util.Date(Long.parseLong(upToNCharacters)); // System.out.println(time); model.setDate(String.valueOf(timeZoneFormat.format(time))); List

我感到惊讶的是,在执行IEnumerable过程EditMyList后,每个MyIEnumerable对象包含与DBTable相同的数据。但是,我仅对MyList进行了修改,而在MyList被修改后未将其分配给MyIEnumerable

你能解释一下这里发生了什么以及为什么ListMyList引用同一个实例?

MyEInumerable

更新:Public Class DBTable Public Property TableName As String Public Property NumberOfRows As Integer End Class Public Sub EditMyList Dim MyList As New List(Of DBTable) MyList.Add(New DBTable With {.TableName = "A", .NumberOfRows = 1}) MyList.Add(New DBTable With {.TableName = "B", .NumberOfRows = 2}) MyList.Add(New DBTable With {.TableName = "C", .NumberOfRows = 3}) Dim MyIEnumerable As IEnumerable(Of DBTable) = MyList For Each item In MyList item.NumberOfRows += 10 Next End Sub 最后b不等于a的情况。 string也是引用类型,因此将一个变量分配给另一个变量我们将仅复制引用。然而,最后结果与第一个例子(由@Sefe解释)有不同的结果

String

2 个答案:

答案 0 :(得分:1)

List是参考类型。这意味着它是在堆上创建的,并且您的MyList变量只包含一个引用(有时不正确地称为"指针")到列表中。当您将MyList分配给MyEnumerable时,您不会复制整个列表,只需复制参考。这意味着您对(一个)列表所做的所有更改都会被所有引用反映出来。

如果您想要新列表,则需要创建它。您可以使用the list constructor

Dim MyIEnumerable As IEnumerable(Of DBTable) = New List(Of DBTable)(MyList)

由于您不需要列表,但IEnumerable您还可以调用列表的ToArray方法:

Dim MyIEnumerable As IEnumerable(Of DBTable) = MyList.ToArray

您也可以使用LINQ:

Dim MyIEnumerable As IEnumerable(Of DBTable) = MyList.ToList

String的行为而言,.net中的字符串是不可变的。这意味着一旦创建,它们就无法更改。字符串操作(例如连接)将始终创建新字符串。换句话说:您必须手动为列表执行的复制操作是为字符串自动完成的。这就是为什么你看到字符串的类似行为和值类型的原因。

此外,如果字符串是可变的,您问题中的赋值操作仍然会表现相同。分配a = "xxx"后,您将a的引用从"bbb"更新为"xxx"。然而,这不会影响b,它仍然保留其旧参考。

答案 1 :(得分:1)

使用ToList()扩展方法创建另一个List

Dim newCollection = MyList.ToList()

但请注意,DBTable的实例仍会引用相同的项目

要创建“完整”副本,您需要为集合中的每个项目创建DBTable的新实例

Dim newCollection = MyList.Select(Function(item)
                                      return new DBTable
                                      {
                                          .TableName = item.TableName,
                                          .NumberOfRows = item.NumberOfRows
                                      }
                                  End Function).ToList()


For Each item in MyList
    item.NumberOfrows += 10 ' will not affect on the newCollection items
Next