【问题标题】:How to change a class variable?如何更改类变量?
【发布时间】:2019-12-03 05:32:21
【问题描述】:

我在一个非常基本的 C# 控制台游戏(文本冒险)中有一个类,我想在代码的其他地方修改一个变量。我知道 C# 不允许使用全局变量,但这本质上就是我想要的。

我是编程初学者。我很困惑,我一直无法找到这个问题的答案。这确实是我所追求的范围问题。哪些变量可以相互“对话”。我将在下面包含一个简单的示例。

类中的所有这些字段都将 在各种方法中的其他地方进行修改。

class Player        
{
    public int health = 100;
    public string armor = "none";
    public string gun = "none";
    public int money = 1000;
}

    public static void AddMoney()
{
    var NewPlayer = new Player();
    NewPlayer.money += 1500;
}

所以我想基本上知道如果全局变量在 C# 中不是一个东西,我应该做什么。

【问题讨论】:

  • 嗯,你证明了你确实能够使用NewPlayer.money 更改公共(又名全局)变量。所以有什么问题?您在寻找static 成员实施吗?
  • 字段变量不应公开。使它们成为属性。
  • 我建议你阅读类构造函数
  • 用你自己的话说,什么是类?什么是对象?您对它的工作原理的现有理解是什么?

标签: c# class variables scope


【解决方案1】:

在 C# 中有几种更新实例变量的方法:使用 properties 或 Java 中的 setter 或实例方法。以下代码向您展示了其中的一些。

最终,您要做的是将播放器实例的引用传递给不同的方法,并让它们使用属性/方法来更新实例变量:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var p1 = new Player();

            p1.Health = 5000;
            p1.Armor = "Helmet";
            p1.AddMoney(200);

            Console.WriteLine($"Health: { p1.Health }");

            var enemy = new Enemy();

            enemy.Shoot(p1);

            Console.WriteLine($"Health after being shot: {p1.Health}");
        }
    }

    class Player
    {
        private string armor;
        private int money;

        public int Health { get; set; }

        public string Armor
        {
            get => armor;
            set
            {
                Console.WriteLine("Updating armor.");
                armor = value;
            }
        }

        public int Money { get; private set; }

        public void AddMoney(int money)
        {
            // More complex logic here, example: synchronization.
            this.money = money;
        }
    }

    class Enemy
    {
        public void Shoot(Player p)
        {
            p.Health -= 500;
        }
    }
}

这是面向对象的做事方式。至于应用范围变量意义上的全局变量,可以参考this。

您也可以将Player 设为singleton。这更像是一种设计选择,而不是实际的 C# 东西。我不打算在这里讨论单例模式。如果您搜索单身人士及其优缺点,您会听到很多:)

【讨论】:

    【解决方案2】:

    免责声明:您可以将 Player 设为 static 类,这可能会按照您的意愿行事,但这样做是不明智的,因为它会将您限制在单个玩家对象中,并且不容易进行单元测试,除其他问题外。见When to use static classes in C#。

    你必须明白你Player是一个类。将其视为Player 对象外观的蓝图。我通常会用汽车来比喻:你买了两辆丰田普锐斯。各方面都一样。你带一个去喷漆店并在上面画一个设计。其他普锐斯有变化吗?不。这与var player1 = new Player(); var player2 = new Player(); 相同 - 它们都是“播放器”类型,但它们不是同一个播放器。

    现在考虑您的 AddMoney 方法:

    public static void AddMoney()
    {
        var NewPlayer = new Player();
        NewPlayer.money += 1500;
    }
    

    您正在创建一个仅存在于AddMoney 方法中的播放器。一旦在外面,它实际上就不再存在了(东西不会立即从内存中删除,但garbage collection 还不是你应该关心的话题)。

    由于Player 是class,所以它是reference type,这意味着将其传递给方法将传递对内存中相同对象的引用。这意味着我们可以更改AddMoney 中的对象,它将反映在调用者中。请注意,我们无法替换该对象 - 为此您需要 ref keyword(但这也是另一个主题)。

    public static void AddMoney(Player player)
    {
        player.money += 1500;
    }
    

    例子:

    var player = new Player();
    player.money = 8500;
    Console.WriteLine(player.money); // 8 500
    AddMoney(player);
    Console.WriteLine(player.money); // 10 000
    

    Try it online

    或者,如果你想创建一个播放器,你可以创建一个工厂方法:

    public static Player CreatePlayer()
    {
        return new Player
        {
            money = 1500
        };
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2015-01-21
      • 2015-07-11
      相关资源
      最近更新 更多