从导数恢复到基类

本文关键字:基类 恢复 | 更新日期: 2023-09-27 17:58:11

我已经初始化了Die类中的一个对象"_currDie",运行了一个if语句将该对象更改为派生类对象,然后运行一个方法。

问题是,当它离开if语句时,它似乎正在恢复到基类。

namespace CharacterSheet
{
public partial class DiceRoller : Form
{        
     Die _currDie;
    public DiceRoller()
    {
        InitializeComponent();
    }
    private void chooseSides_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (chooseSides.SelectedItem.ToString() == "D4")
        {
            D4 _currDie = new D4();
        }
        if (chooseSides.SelectedItem.ToString() == "D6")
        {
            D6 _currDie = new D6();
        }
        if (chooseSides.SelectedItem.ToString() == "D8")
        {
            D8 _currDie = new D8();
        }
        if (chooseSides.SelectedItem.ToString() == "D10")
        {
            D10 _currDie = new D10();
        }
        if (chooseSides.SelectedItem.ToString() == "D20")
        {
            D20 _currDie = new D20();
        }
        if (chooseSides.SelectedItem.ToString() == "Percentile")
        {
            Percentile _currDie = new Percentile();
        }

    }

    private void Roll_Click(object sender, EventArgs e)
    {
        _currDie.Roll();
        string currResult = Convert.ToString(_currDie.RollResult);
        MessageBox.Show(currResult);
    }

}
}

这是基本类

namespace CharacterSheet
{
public class Die
{
    public int Sides { get; set; }
    private Random rng = new Random();
    public int rollResult;
    public int RollResult
    {
        get
        {
            return rollResult;
        }
    }
    public virtual void Roll()
    {
        rollResult = rng.Next(Sides) + 1;
    }

}
}

我用测试的衍生类

namespace CharacterSheet
{
public class D4:Die
{
  public D4 ()
    {
        Sides = 4;
    }
}
}

我在第一个if语句处设置了断点,当我逐步完成时,我可以清楚地看到_currDie.Roll()上的_currDie从D4对象变为Die对象;此时,我得到一个System.NullReferenceException

我尝试过在不定义类的情况下实例化_currDie,但由于没有对象的Roll方法,该方法会出错。

从导数恢复到基类

在每个if语句中,您都在声明一个新的局部变量,例如

if (chooseSides.SelectedItem.ToString() == "D4")
{
    D4 _currDie = new D4();
}

这将初始化新的_currDie变量,但随后您就到达了块的末尾,因此它毫无用处。您要做的是为现有字段分配一个新值:

if (chooseSides.SelectedItem.ToString() == "D4")
{
    _currDie = new D4();
}

注意这里没有声明,因为您没有试图声明一个新的变量。您只是为现有变量赋值。

顺便说一句,如果没有别的,你最好用一句switch语句:

switch (chooseSides.SelectedItem.ToString())
{
    case "D4": _currDie = new D4(); break;
    case "D6": _currDie = new D6(); break;
    case "D20": _currDie = new D20(); break;
    ...
}

我个人会做一些稍微不同的事情,可能有一个Dictionary<string, Func<Die>>,但那是另一回事。

您正在用每个if…中的作用域变量覆盖您的成员变量_currentDie

你在类中定义了你的_currDie成员,这没关系

public partial class DiceRoller : Form
{        
    Die _currDie; // define the die member, OK
    // <SNIP>

然后稍后创建一个名为__curDie的新变量(编译器必须警告您检查输出窗口)

    // _currDie means this._currdie
    if (chooseSides.SelectedItem.ToString() == "D20")
    {
        D20 _currDie = new D20(); // you create a new variable named _currDie in this scope...
    } // the scope end so now __curdie means this.__curdie

修复非常简单:

    if (chooseSides.SelectedItem.ToString() == "D20")
    {
        _currDie = new D20(); // assign the value to the member __curDie
    }