从衍生物转向基类

时间:2016-07-22 15:52:13

标签: c# visual-studio class

我在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从一个D4对象变为_currDie.Roll()上的一个Die对象; 此时我得到一个System.NullReferenceException

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

2 个答案:

答案 0 :(得分:4)

在您的每个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>>,但这是另一回事。

答案 1 :(得分:0)

您正在使用范围变量覆盖成员变量_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
    }