简体   繁体   English

在C#中的列表内修改列表

[英]Modifying list inside list in C#

I am trying to modify the value inside the inner list by iterating the list. 我试图通过迭代列表来修改内部列表中的值。 However, i keep getting the same outcome for the inner list irrespective of the outer list. 但是,无论外部列表如何,我对于内部列表都会得到相同的结果。 I expect the outcome of the maxSpeed is different for different vehicle. 我预计maxSpeed的结果对于不同的车辆会有所不同。

Hope someone could help on this. 希望有人可以对此提供帮助。

Note that this is not a random number generator problem. 请注意,这不是随机数生成器问题。 This is just a sample code that I produce and this issue do exist in my project code without the use of random number generator. 这只是我产生的示例代码,而在不使用随机数生成器的情况下,此问题确实存在于我的项目代码中。

Run C# code here 在这里运行C#代码

List<Vehicle> mainList = new List<Vehicle>();
List<Properties> defaultPropertyList = new List<Properties>{
    new Properties() { maxSpeed = 0, isTwoDoor = true },
    new Properties() { maxSpeed = 0, isTwoDoor = true },
};


mainList.Add(
    new Vehicle() {
        number = 1,
        property = new List<Properties>(defaultPropertyList)
    }
);
mainList.Add(
    new Vehicle() {
        number = 2,
        property = new List<Properties>(defaultPropertyList)
    }
);           

foreach(Vehicle vehicle in mainList) {
    Random rnd = new Random();
    vehicle.property.ForEach(x => x.maxSpeed =  rnd.Next(1, 100));
}

The problem is that when you initialize the property field for each vehicle, you are adding references to the same two Properties objects (defined at the top). 问题在于,当您为每辆车初始化property字段时,您将添加对相同的两个Properties对象(在顶部定义)的引用。 So they exist in all vehicles, and when you modify one, it is modified in both places (since it is the same reference). 因此它们存在于所有车辆中,并且当您修改一个时,在两个地方都对其进行了修改(因为它是相同的参考)。

You will want to instead make copies of the objects in the defaultPropertyList when you initialize a new vehicle. 初始化新载具时,您将需要在defaultPropertyList对象的副本。 Then they will exist independently. 然后它们将独立存在。

One approach: Make a new constructor for Vehicle that takes in the default properties, and copy them there. 一种方法:为Vehicle构造一个新的构造函数,该构造函数采用默认属性,然后将其复制到那里。

public Vehicle(List<Properties> defaultProps) 
{
  property = new List<Properties>();
  foreach (var p in defaultProps)
  {
    var newProp = new Properties {
                                    maxSpeed = p.maxSpeed,
                                    isTwoDoor = p.isTwoDoor
                                    // add any other properties here
                                 };
    property.Add(newProp);
  }
}

defaultPropertyList is just one list containing one set of items. defaultPropertyList只是一个包含一组项目的列表。 Each Vehicle has the same instance of List<Properties> . 每个Vehicle具有相同的List<Properties>实例。 There's not one per Vehicle . 有没有每Vehicle There's just one, and they're all sharing it. 只有一个,他们都在共享它。 That's why no matter how you change the properties, they all have the same properties. 这就是为什么无论您如何更改属性,它们都具有相同的属性。

To fix it, don't create one and share it. 要解决此问题,请不要创建一个共享。 Just create as many as you need. 只需创建所需的数量即可。 Maybe this isn't you, but when I started off I was afraid of creating lots of objects and thought I could optimize by creating as few as possible. 也许不是你,但是当我刚开始的时候,我害怕创建很多对象,并认为我可以通过创建尽可能少的对象来进行优化。

While it's true that we don't want to unnecessarily create lots of expensive objects, there's no need to be stingy about it. 的确,我们不想不必要地创建许多昂贵的对象,但不必为此小气。 Create as many as you need. 根据需要创建多个。 For example, in a web application it's impossible to even keep track of how many objects get created just to respond to a single request. 例如,在Web应用程序中,仅跟踪单个请求就不可能跟踪创建了多少个对象。

You could just do this: 您可以这样做:

Random rnd = new Random(); // Despite what I just said,
                           // you only need one of these this time.
foreach(Vehicle vehicle in mainList) {        
    vehicle.property = new List<Properties>{
        new Properties() { maxSpeed = rnd.Next(1, 100), isTwoDoor = true },
        new Properties() { maxSpeed = rnd.Next(1, 100), isTwoDoor = true },
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM