【问题标题】:How can I use a string to call an object in C#?如何在 C# 中使用字符串调用对象?
【发布时间】:2019-11-01 19:40:46
【问题描述】:

我目前正在制作一个简单的基于控制台的 RPG 地下城游戏,我对 C# 还很陌生,我在学校上过视觉基础课程,我已经玩了大约一个月的 unity。

我的问题是,我正在编写玩家将遇到的第一场战斗。我已经构建了一些武器,我希望能够用单独的字符串调用人员当前的武器,例如,我当前的武器是匕首,或者对象 wp1,我希望我的“武器”附加到 wp1以某种方式,这样我就可以做类似的事情, Console.WriteLine("Damage: " + weapon.dmg);而不是硬编码wp1.dmg,这样在游戏制作过程后期,当玩家有机会购买更好的武器时,我可以用变量来做,例如玩家现在有短剑(wp2)

private string weapon = "wp2"; ... Console.WriteLine("Damage: " + weapon.dmg);

我试图简单地说, String weapon = wp1;

然后调用 Wea​​pon.dmg,但这不起作用,因为它认为我正在尝试调用 武器.dmg,而不是 wp1.dmg


//players base damage
int damage = 0;

//players strength attribute
int strength = 0;

//weapon constructor
class wp
        {
            public int dmg;
            public int cost;
            public string name;

            public wp(int d, int c, string n)
            {
                dmg = d;
                cost = c;
                name = n;
            }
        }

//three weapons that are constructed
wp wp1 = new wp(1, 25, "dg");
wp wp2 = new wp(3, 100, "ss");
wp wp3 = new wp(5, 250, "ls");

//the current weapon string
public string weapon = "wp1";

void attack()
{
   //calculates damage based off of the players damage, strength, and weapon
   int newDamage = damage * strength + (weapon.dmg);
}

预期结果: 程序应该使用玩家当前武器的伤害值

实际结果,程序试图找到武器的dmg值,但这是不可能的,因为“武器”只是一个字符串,所以会抛出错误

【问题讨论】:

  • 不要将当前武器存储为string.. 将其存储为wp 类型。
  • ...然后将当前武器 (wp) 对象传递给 Attack 方法,以便每次都使用当前武器
  • 今天是初学者学习好习惯的好日子。不要成为“原始痴迷”的牺牲品,尤其是弦乐。初学者倾向于养成使用基本类型(如字符串)的习惯。不。您收到错误是因为这是错误的做法。
  • 在我们查看您的代码时:也要养成正确命名事物的习惯。如果您输入class Weapon 而不是class wp,您不会死得更早。类和方法应该是CasedLikeThis。永远不要公开领域;改为使用公共财产。现在就学习好习惯,以后就不必再改了。
  • 另外,不要养成不良的命名习惯。给事物起描述性的名称。 wp 应该是 Weapondmg 应该是 Damage。假装你正在阅读别人的代码,看看你是否能根据他们的名字推断出什么东西。如果你不能,你选择了一个坏名字。 (编辑)是的,Eric Lippert 说的。

标签: c# variables


【解决方案1】:

正如我在上面的评论中所说,作为初学者,现在就养成良好的习惯,以后就不必再改掉这些习惯了。让我们看看我们如何设计您的系统。从精心设计的类层次结构开始。假设我们有三种武器:剑、匕首和棍棒。它们的共同点进入了一个抽象基类:

abstract class Weapon
{

他们有什么共同点?损坏,成本和名称。因此,为这些创建抽象的只读属性:

    public abstract int Damage { get; }
    public abstract decimal Cost { get; }
    public abstract string Name { get; }
}

现在创建一些派生类。您是否打算进一步扩展它们?如果没有,请密封它们:

sealed class Sword : Weapon 
{
    public override int Damage => 10;
    public override decimal Cost => 12.5m;
    public override string Name => "normal sword";
}

等等。

现在对播放器做同样的事情。假设我们可以更改玩家的武器,但不能更改他们的名字。所以Name应该是只读属性,Weapon应该是读写属性:

sealed class Player
{
  public string Name { get; private set; }
  public Weapon Weapon { get; set; }
  public int Strength { get; private set; }
  public int BaseDamage { get; private set; }
  public Player(string name, Weapon weapon, int strength, int baseDamage)
  {
    this.Name = name;
    this.Weapon = weapon;
    this.Strength = strength;
    this.BaseDamage = baseDamage;
  }
}

现在我们可以制作一些武器了:

Weapon weapon1 = new Sword();
Weapon weapon2 = new Dagger();
Weapon weapon3 = new Club();
Player fighter = new Player("Bob", weapon3, 5, 10);

或者,更好:

var weapons = new List<Weapon> { new Sword(), new Dagger(), new Club() };
// weapons is indexed 0, 1, 2.
Player fighter = new Player("Bob", weapons[2], 5, 10);

如果你手头有一个玩家:

static void Attack(Player p)
{
  int damage = p.BaseDamage * p.Strength + p.Weapon.Damage;
  string text = $"Player {p.Name} attacks with {p.Weapon.Name}";

没有用于引用对象的字符串!除了 text 之外,不要使用字符串。对对象的引用应该是对对象的引用,而不是字符串。

现在,仅限高级玩家,有时您确实需要通过字符串查找某些内容。您在 C# 中执行此操作的方式是:

var d = new Dictionary<string, Weapon> {
  { "weapon1", new Sword() },
  { "weapon2", new Dagger() },
  { "weapon3", new Club() } 
};
Weapon w = d["weapon1"]; // w is a Sword.

默认情况下不要这样做。这不是在 C# 中引用某些内容的正常方式。

【讨论】:

  • 我认为字典绝对是对魔术索引的改进,但如果你还不是一个 "高级玩家" 将变量映射到索引号,可以通过 @987654331 之类的有用方法@ 会更好。
  • 非常感谢您的帮助,我一定会尝试一下。
  • 感谢您的回答!你的建议帮助我提高了,而且我在面向对象编程方面的技能已经有很长一段时间了。
【解决方案2】:

实现你想要的一种方法:

if(weapon=="wp1")
 //use wp1 object here.

但更好的方法是将您的 3 个 wp 放入一个列表或数组中(因为您实际上是硬编码了一个包含 3 个对象的列表)。然后 wp1 将在

wpArray[0];

【讨论】:

  • 您可以从 wp 数组访问武器 dmg。 wpArray[0].dmg
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多