繁体   English   中英

C#更新对象列表中的值也将更新其他值

[英]C# Updating a value in a list of objects is updating other values too

我当时正在研究一个简单的回合制RPG游戏。 我当时在战斗系统上工作。 我让它与1个敌人一起使用,并想对其进行更新以在多个敌人上使用。 我产生了多个敌人,但针对他们却遇到了问题。

基本上,敌人存储在一个称为“实际敌人”的列表中。 敌人是在运行时生成的,并且可能在1-3之间。 生成一个标签来显示敌人的名字,并通过双击敌人来选择它。

问题似乎在于敌人的名字。 他们有一个名为characterName的属性来识别敌人。 问题是,可能有2个或更多相同类型的字符(例如3x妖精)。 因此,在生成敌人的代码中,如果列表中已经存在一个,我想在characterName上添加1。 这个想法是给每个敌人一个唯一的名字。

问题是,当我尝试执行此操作时,它会更改所有同名敌人的值,并且这一切都搞砸了。 这是代码的相关部分:

if (EnemyExists(e)) {
    e.characterName += c.ToString();                            
}

c只是一个正在使用的计数器,让我知道它是敌人1、2还是3。

EnemyExists函数如下:

public bool EnemyExists(Enemy e) {
    bool exists = false;
    int eCount = 0;

    foreach (Enemy en in actualEnemies) {
        if (en.characterName == e.characterName) {
            eCount++;
        }
    }

    if (eCount > 1) {
        exists = true;
    }

    return exists;
}

请注意,所有敌人都以默认名称开始。 对于我正在研究的这个示例,只有两种敌人。 游戏选择1-3之间的随机数,以确定有多少个敌人。 每个敌人将是2个预先定义的敌人之一,并再次随机选择。 这就是为什么我只想在已经存在的名称的末尾添加一个数字。

我怀疑这与我创建敌人列表有关:

public void CreateActualEnemies() {
    int r;
    int potEnemyNum = potentialEnemies.Count;         
    int numEnemies;
    Random rand = new Random();
    numEnemies = rand.Next(1, 4 );

    for (int i = 0; i < numEnemies; i++) {
        r = rand.Next(0,potEnemyNum);
        Enemy ene = new Enemy();
        ene = potentialEnemies.ElementAt(r);
        actualEnemies.Add(ene);
    }

    DisplayEnemyDetails();
}

当我添加实际敌人时,是否只是在指向潜在敌人中的地址,所以即使我实例化了一个新的敌人,如果每个敌人都具有相同的名称,它都指向同一位置吗? 我需要正确复制对象吗?

已经很晚了,我很累,但是我觉得我越来越近了,任何帮助都会很大,谢谢。

编辑:

敌人等级:

public class Enemy:Character {
    public int xpGiven { get; set; }
    public LootTable lootTable { get; set; }
    public int goldDropped { get; set; }
    public bool alive { get; set; }
    public NamedTimer timer { get; set; }

    public Enemy() {
        alive = true;
        xpGiven = 10;
        lootTable = new LootTable();
        goldDropped = 10;
        timer = new NamedTimer();            
    }
}

分解您的问题:

当我添加实际敌人时,是否只是在指向潜在敌人中的地址,所以即使我实例化了一个新的敌人,如果每个敌人都具有相同的名称,它都指向同一位置吗?

通过做

Enemy ene = new Enemy();

您必须在内存中使用“空白”值引用创建新的指针。 但是,既然你做了

ene = potentialEnemies.ElementAt(r);

您使用对列表中元素的引用来覆盖它。 因此,您对ene对象所做的任何更改都将反映列表中的项目。

如果要隔离所说的更改,请尝试使用MemberwiseClone

从MSDN给出的示例中:

public class Person 
{
    public int Age;
    public string Name;
    public IdInfo IdInfo;

    public Person ShallowCopy()
    {
       return (Person) this.MemberwiseClone();
    }

    public Person DeepCopy()
    {
       Person other = (Person) this.MemberwiseClone();
       other.IdInfo = new IdInfo(IdInfo.IdNumber);
       other.Name = String.Copy(Name);
       return other;
    }
}

1:属性名称应以C#中的大写字母开头。 public int xpGiven { get; set; } public int xpGiven { get; set; } public int xpGiven { get; set; }应该是public int XpGiven { get; set; } public int XpGiven { get; set; } public int XpGiven { get; set; } 如果它是一个类变量(未定义get或set),则以小写字母开头。 为了更容易地从局部变量中识别类变量,程序员通常以_开头,尽管这不是强制性的。

2:做== ,请注意enemyA == enemya将返回false。 使用enemyA.Equals(enemya, StringComparison.OrdinalIgnoreCase)忽略资本差异。

3:

public void CreateActualEnemies()
    {
        int r;
        int potEnemyNum = potentialEnemies.Count;         
        int numEnemies;
        Random rand = new Random();
        numEnemies = rand.Next(1, 4 );
        for (int i = 0; i < numEnemies; i++)
        {
            r = rand.Next(0,potEnemyNum);
            Enemy ene = new Enemy();
            ene = potentialEnemies.ElementAt(r);
            actualEnemies.Add(ene);
        }
        DisplayEnemyDetails();
    }

应该:

public void CreateActualEnemies()
    {
        Random rand = new Random();
        int numEnemies = rand.Next(1, 4 );

        for (int i = 0; i < numEnemies; i++)
        {
            Enemy ene = new Enemy();
            ene.characterName = "" + ene.GetType().Name + " " + i; // or something similar to give the ene a unique name.
            actualEnemies.Add(ene);
        }
        DisplayEnemyDetails();
    }

暂无
暂无

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

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