【问题标题】:Ref on a list not changing values参考不改变值的列表
【发布时间】:2013-08-23 10:14:04
【问题描述】:

我正在从 Java 转到 C#,并且正在编写一些示例程序。现在我遇到了一个不同对象的列表(IUnit),当我调用列表中的某个值来更改它的值时,它会更改所有值。我添加了对列表的引用 - 根据其他堆栈溢出问题。

所以我有以下课程

interface IUnit
{
    int HealthPoints { set; get; }
    String ArmyType { get; }
}

这是我用来创建陆军类型(海军陆战队/步兵)列表的基类。实现是相同的,期望更改类中的值。

public class Infantry : IUnit
{
    private int health = 100;
    protected String armyType = "Infantry";
    public int HealthPoints
    {
        get
        {
            return health;
        }
        set
        {
            health = value;
        }
    }
    public String ArmyType
    {
        get
        {
            return armyType;
        }
    }

然后我用下面的代码初始化列表

 List<IUnit> army = new List<IUnit>(); 
 Infantry infantry = new Infantry();
 Marine marine = new Marine(); 
 army.Add(Marine);

然后我有一个方法,它只是从健康点中扣除 25。

    public void ShotRandomGuy(ref List<IUnit> army)
    {
        army[0].HealthPoints = army[0].HealthPoints - 25;
    }

然后我调用该方法,如下所示。

 battle.ShotRandomGuy(ref army);

但是,它会从该列表中的所有对象中删除 25 个。我将如何阻止它这样做?我添加了对列表的引用,所以我认为它会将其从原始列表中删除。我需要克隆列表吗?这行得通吗?

还是更多的设计问题?

谢谢!

【问题讨论】:

标签: c# list object


【解决方案1】:

看起来您要多次添加相同的单元实例到列表中。因此,所有列表项都指向内存中的单个对象。修改任何项目都会修改该对象。

List<IUnit> army = new List<IUnit>(); 
Infantry infantry = new Infantry();    

for(int i = 0; i < 10; i++)
{
    // adds same instance each time        
    army.Add(infantry);
}

您应该在将单位添加到列表时实例化新单位。例如

List<IUnit> army = new List<IUnit>(); 

for(int i = 0; i < 10; i++)
{
    // create new instance each time
    Infantry infantry = new Infantry();
    army.Add(infantry);
}

顺便说一句,这里不需要ref

public void ShotRandomGuy(List<IUnit> army)
{
    Random r = new Random();
    var unit = army[r.Next(army.Count)];
    unit.HealthPoints -= 25;
}

【讨论】:

  • 啊,这完全有道理。那么我该如何为每个单元创建一个不同的实例,从而在内存中拥有多个对象呢?
  • 啊,对不起-我已经这样做了。但它仍在改变所有对象的值。我应该举一个更好的例子。对不起。
  • @JamesReeves 你能在哪里向军队添加部队吗?我完全确定您使用的是第一个示例中的方法
  • OMG - 谢谢,我简直不敢相信我是怎么错过的。很明显,我需要在 for 循环中实例化对象 - 非常感谢。
【解决方案2】:
  1. 如果您不打算将军队设置为另一个列表,则无需将列表作为参考传递
  2. 您是否忘记将步兵添加到列表中? 名单军队 = 新名单(); 步兵 步兵 = new Infantry(); 海洋海洋 = 新海洋(); Army.Add(海军陆战队);

【讨论】:

  • 否 这是一个例子。我应该包括army.add(步兵)。对不起
  • 你能提供你的应用程序的完整代码吗?示例代码中没有这种行为的原因
【解决方案3】:

您可以将infantrymarine 保留在列表中,并使用for 对它们进行排序。

这样的东西可以用于实例化列表。

breadCollection = new List<InteractiveObject>();


for(int i = 0; i < totaltObjects; i++)
    breadCollection.ElementAt(i).Add(new InteractiveObject());

当您必须访问list 的内容进行更改时,请执行以下操作。

int shotUnit?;    

shotUnit = unitNumber
if(shot != null)
{
    breadCollection.ElementAt(i).Remove(alive)
    breadCollection.ElementAt(i).Add(dead)
    shotUnit = null;
}

我相信这会解决您的问题。你也可以用

写一些东西来改变属性的数值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多