方法不能从整型参数中取值

本文关键字:参数 整型 不能 方法 | 更新日期: 2023-09-27 18:01:45

我目前只学习了一个星期的c#,所以为任何愚蠢的错误道歉,但我试图在一个开关语句中调用一个方法,从给方法的参数中拿走一个在列表中声明的整数值,在这种情况下,参数是健康的currEnemy对象,但是当currEnemy。健康值被打印到控制台,它的值是不变的,我不知道为什么。

存储当前值对应的整数值的列表。在敌人类中,生命值变量被设置为整数值的long带走:

public List<Weapon> myWepList = new List<Weapon>(){
    new Weapon {name = "Dagger", dmg = 10, stamDrain = 5},
    new Weapon {name = "Sword", dmg = 20, stamDrain = 20},
    new Weapon {name = "Halberd", dmg = 40, stamDrain = 20}
};
public int health{ get; set; }

玩家类中应该从敌人那里拿走"dmg"值的方法。生命值和设定敌人。运行状况设置为新值:

public void charAttack(int enemyHealth)
{
    enemyHealth -= equippedWep[0].dmg;
}

然后调用上述方法的代码显示当前值。运行状况的新值:

enum PlayerInput
{
    Attack,
    Block,
}
while (gameStart == true) //this part onwards is stored in the main method
{
    string playerInput = Console.ReadLine().ToUpper();
    PlayerInput inputChoice;
    Console.WriteLine("Type 'attack' to attack the enemy");
    if (Enum.TryParse<PlayerInput>(playerInput, true, out inputChoice))
    {
        switch (inputChoice)
        {
            case PlayerInput.Attack:
                currPlayer.charAttack(currEnemy.health);
                Console.WriteLine("Enemy Health is {0}", currEnemy.health);
                break;
            default:
                break;
        }
    }
}

考虑到我对c#完全陌生,如果能给我一些关于我的代码的一般性建议,我也会很感激,所以任何建设性的建议都会很棒,谢谢。

方法不能从整型参数中取值

此方法:

public void charAttack(int enemyHealth)
{
    enemyHealth -= equippedWep[0].dmg;
}

…基本上毫无意义。语句enemyHealth -= ...只影响名为enemyHealth参数。它根本不会改变currEnemy.Health——因为方法参数是按值传递的。换句话说,这个过程是:

  • currEnemy.health被评估
  • 该值作为enemyHealth
  • 的初始值
  • 方法执行
  • enemyHealth的最终值根本不使用

参见我关于参数传递的文章。

有多种方法可以解决这个问题——例如,您可能想要:
currPlayer.Attack(currEnemy);

,其中Attack方法看起来像:

public void Attack(Enemy enemy)
{
    Weapon weapon = equippedWep[0];
    enemy.Health -= weapon.Damage;
}

请注意,最后一行与前面的代码非常不同,因为它将设置之后的enemy.Health的值…您不仅要更改参数,还要更改对象的状态。

不能更改传递给函数的值。它在所有语言中都是一样的,不仅仅是c#。

int a = 0;
function changeA(int a)
{
    a = 1;
}
print a; // show 0, not 1

您可以更改对象中包含的值:

public class Obj
{
    public int health{ get; set; }
}
var o = new Obj();
function changeHealth(Obj o)
{
    o.health = 1;
}
print o.health; // show 1

c#之类的,这是你首先要了解的。

对于你的实际问题,这里有一个建议:传递代表敌人的实际对象,而不仅仅是他的生命值。然后推断敌人的生命值

public void charAttack(Player enemy)
{
    enemy.health -= equippedWep[0].dmg;
}
while (gameStart == true) //this part onwards is stored in the main method
{
    string playerInput = Console.ReadLine().ToUpper();
    PlayerInput inputChoice;
    Console.WriteLine("Type 'attack' to attack the enemy");
    if (Enum.TryParse<PlayerInput>(playerInput, true, out inputChoice))
    {
        switch (inputChoice)
        {
            case PlayerInput.Attack:
                currPlayer.charAttack(currEnemy);
                Console.WriteLine("Enemy Health is {0}", currEnemy.health);
                break;
            default: break;
        }
    }
}

c#按值传递int,这意味着你只能在方法中获得值的副本。要解决这个问题,你可以像这样解析敌人对象:

public void charAttack(Enemy enemy)
{
    enemy.health -= equippedWep[0].dmg;
}

这会影响敌人的生命值。

问题在于您的charAttack方法声明。enemyHealth参数没有通过引用传递,因此您实际上是在修改变量的副本,而不是原始的(这是通过值传递的调用)。

你可以通过引用

传递参数,这意味着你要修改原来的

public void charAttack(ref int enemyHealth)
{
    enemyHealth -= equippedWep[0].dmg;
}

或者您可以返回修改后的结果并将原始值设置为它:

public int charAttack()
{
    return equippedWep[0].dmg;
}
i = charAttack();

您需要通过引用传递您的敌人健康值。c#默认是按值传递,这意味着该方法会获得该值的副本。通过引用传递实际的int对象

public void charAttack(int enemyHealth)
{
    enemyHealth -= equippedWep[0].dmg;
}

基于上述方法,您所经历的行为是可以预料的。在调用此方法时,您实际上不是在声明"更改调用currEnemy.health",而是更改enemyHealth。问题是currEnemy.health是通过值传递的(就像传递的文字值一样,而不是表示该值的"对象"),而不是通过引用。

有两种(或更多)方法可以解决这个问题:

一个可以参考敌人的生命值:

public void charAttack(ref int enemyHealth)
{
    enemyHealth -= equippedWep[0].dmg;
}

并像这样调用你的方法:

currPlayer.charAttack(ref currEnemy.health);

或者从你的方法返回一个新的敌人生命值:

public int charAttack(int enemyHealth)
{
    return enemyHealth - equippedWep[0].dmg;
}

和调用:

currEnemy.heatlh =  currPlayer.charAttack(currEnemy.health);