2016-07-22 10 views
0

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; 
    } 

} 
} 

でテストしてきた派生クラスであります私は、_currDieがD4オブジェクトから_currDie.Roll()のDieオブジェクトに変化することを明確に見ることができます。 どの時点でSystem.NullReferenceExceptionが発生するか

クラスを定義せずに_currDieのインスタンスを作成しようとしましたが、オブジェクトのRollメソッドがないためエラーが発生します。

答えて

4

ifステートメントでは、新しいローカル変数を宣言しています。新しい_currDie変数を初期化しますが、その後はブロックの終わりを打つ、そしてそれは無用だ

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

。新しい変数を宣言しようとしていないので、ここで宣言の欠如に注意してください

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>>を持つ、わずかに異なる何かをしたいが、それは別の問題です。

+0

私はあまりにも速く入力します。私はあきらめます –

+0

最初にswitch文を試しましたが、同様の例外が発生しました。問題が新しいローカル変数を宣言していたことを知ったので、もう一度試してみましょう。ありがとう! –

0

場合は、各スコープの変数を使用してメンバ変数_currentDieをオーバーライドしているが...

あなたのクラスであなたの_currDieメンバーを定義し、それはあなたが新しい変数を作成するには、後で

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

次にOKです__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 
    } 
関連する問題