2014-05-12 71 views
0

這裏是問題: 我試圖在類的窗簾方法中觸發事件。 例如,我得到了一個名爲clMage的類,它從clUnits繼承,並且獲得了公共方法attMagicMissle(clUnit aU)。 那麼這裏是爲clUnits聲明代碼:NullReferenceExeption在事件觸發時未處理

public class clUnits 
    { 
     public int iHitPoints { get; set; } 
     public int iDamage { get; set; } 
     public ArmorType unitArmor { get; set; } 
    } 

這裏是它的clMage是麻煩的方法:

public class clMage : clUnits 
    { 
     public event evtDamageDone damageDealtToSoldier; 
     public event evtDamageDone damageDealtToArcher; 
     public event evtDamageDone damageDealtToMage; 

     public clUnits currentTarget { get; set; } 

     public AttackType mageAttack { get; set; } 
     public clMage(int iHP, int iDamage, AttackType atType, ArmorType arType) 
     { 
      this.iHitPoints = iHP; 
      this.iDamage = iDamage; 
      this.mageAttack = atType; 
      this.unitArmor = arType; 
     } 

     public int attMagicMissle(clUnits aU) 
     { 
      int iDamageDeals = 0; 
      currentTarget = aU; 

      switch (currentTarget.unitArmor) 
      { 
       case ArmorType.None: 
        { 
         iDamageDeals = iDamage * 2; 
        } 


      break; 
      case ArmorType.Heavy: 
       { 
        iDamageDeals = Convert.ToInt32(iDamage * 1.5); 
        this.damageDealtToSoldier(currentTarget); // Here is the NullReferenceExeption problem starts 
       } 
       break; 
      case ArmorType.Medium: 
       { 
        iDamageDeals = Convert.ToInt32(iDamage * 0.5); 
        this.damageDealtToArcher(currentTarget); 
       } break; 
      case ArmorType.Light: 
       { 
        iDamageDeals = iDamage; 
        this.damageDealtToMage(currentTarget); 
       } break; 
     } 

     return iDamageDeals; 
    } 
} 

這裏進入主():

public delegate int Attack(clUnits aUnit); 
    public delegate void evtDamageDone(object aUnit); 
    public enum AttackType { None, Melee, Range, Mage } 
    public enum ArmorType { None, Heavy, Medium, Light} 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Attack Strikes; 
      clWarrior theSoldier = new clWarrior(750, 75, AttackType.Melee, ArmorType.Heavy); 
      clArcher theArcher = new clArcher(500, 100, AttackType.Range, ArmorType.Medium); 
      clMage theMage = new clMage(250, 150, AttackType.Mage, ArmorType.Light); 

      // Mage actions 
      Console.WriteLine("The mage: "); 
      Strikes = theMage.attMagicMissle; 
      Console.WriteLine("Attack hase damage = {0} attacks the soldier for {1} damage!", theMage.iDamage, Strikes(theSoldier)); 
      Console.WriteLine("Attack hase damage = {0} attacks the archer for {1} damage!", theMage.iDamage, Strikes(theArcher)); 
      Console.WriteLine("Attack hase damage = {0} attacks the mage for {1} damage!", theMage.iDamage, Strikes(theMage)); 

      // Archer actions 
      Console.WriteLine("The archer: "); 
      Strikes = theArcher.attArrowShot; 
      Console.WriteLine("Attack hase damage = {0} attacks the soldier for {1} damage!", theArcher.iDamage, Strikes(theSoldier)); 
      Console.WriteLine("Attack hase damage = {0} attacks the archer for {1} damage!", theArcher.iDamage, Strikes(theArcher)); 

      Console.WriteLine("Attack hase damage = {0} attacks the mage for {1} damage!", theArcher.iDamage, Strikes(theMage)); 

      // Soldier actions 
      Console.WriteLine("The soldier: "); 
      Strikes = theSoldier.attSwordSlash; 
      Console.WriteLine("Attack hase damage = {0} attacks the soldier for {1} damage!", theSoldier.iDamage, Strikes(theSoldier)); 
      Console.WriteLine("Attack hase damage = {0} attacks the archer for {1} damage!", theSoldier.iDamage, Strikes(theArcher)); 
      Console.WriteLine("Attack hase damage = {0} attacks the mage for {1} damage!", theSoldier.iDamage, Strikes(theMage)); 
     } 
    } 

好吧... 我坐着它已經很長一段時間了(9小時)主要在網上衝浪和stackoverflow,但我只是無法得到爲什麼在評論線爲CL法師它給了我這個錯誤,因此無法理解如何解決它!

+2

幾乎'NullReferenceException'的所有情況都是一樣的。請參閱「[什麼是.NET一個NullReferenceException?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)」獲得一些提示。 –

+0

建議:你不必用'cl'將所有類加上前綴。沒有什麼特別的類,他們需要一個特殊的前綴。它只是讓你的代碼更不易讀。 –

+0

Thx鏈接閱讀... –

回答

1

如果沒有人訂閱它,則damageDealtToSoldier爲空,因此調用它將導致NullReferenceException。你需要檢查它是否是空:

if (this.damageDealtToSoldier != null) 
    this.damageDealtToSoldier(currentTarget); 

通常情況下,人們創造這樣的方法來引發事件:

protected virtual void OnDamageDealtToSoldier(object aUnit) 
{ 
    var handler = this.damageDealtToSoldier; 
    if (handler != null) 
     handler(aUnit); 
} 
+0

在一些我已經指出了事件偵聽事件的重要性 - 我用來了解事件的來源沒有指出,如果「偵聽器」不存在,則處理程序將返回null 。除此之外,我認爲必須指出的另一件事是:必須在觸發事件的行之前聲明偵聽器,否則處理程序將返回null。希望我提出的這個話題能夠對其他迷失在「事件迷宮」中的人有所幫助。並且非常感謝Thomas Levesque爲我解決問題提供了領先點。 –

相關問題