2011-03-15 36 views
1

我有這樣一個有趣的問題。獲取NullReferenceException

我有以下結構:

例如,經理類是這樣實現的:

public sealed class Manager : Interface.Abstract.Employee 
{ 
    private Interface.IEmployee chief = null; 
    private readonly Decimal bonuslimit = Convert.ToDecimal(0.4F * Convert.ToSingle(BaseSalary)); 

    public Manager(Person person, DateTime hiredate) 
    : base(person, hiredate) 
    { 
    } 

    public override List<Interface.IEmployee> Subordinates 
    { 
     get; 
     set; 
    } 
    public override Interface.IEmployee Chief 
    { 
     get 
     { 
      return this.chief; 
     } 
     set 
     { 
      //if(value is Associate) 
      //{      
      // throw new SystemException("Associate can't be a chief"); 
      //} 
      this.chief = value; 
     } 
    } 
    public override Decimal Salary 
    { 
     get 
     { 
      var actualbonus = Convert.ToDecimal(0.01F * Convert.ToSingle(this.YearsSinceHired * BaseSalary)); 
      var bonus = (actualbonus > bonuslimit) ? bonuslimit : actualbonus; 
      var additional = 0M; 

      if(this.HasSubordinates) 
      { 
       foreach(Interface.Abstract.Employee employee in this.Subordinates) 
       { 
        if(employee is Sales) 
        { 
         additional += employee.Salary; 
        } 
       } 
      } 
      return Convert.ToDecimal(Convert.ToSingle(additional) * 0.005F) + BaseSalary + bonus; 
     } 
    } 
} 

而 '工廠客戶端',看起來像這樣:

public class EmployeeFactoryClient 
{ 
    private IDictionary<String, IEmployee> employees = new Dictionary<String, IEmployee>();    

    public EmployeeFactoryClient() 
    { 
     this.Factory = new EmployeeFactory();    
    } 
    public EmployeeFactoryClient(IEmployeeFactory factory) 
    { 
     this.Factory = factory;    
    } 
    public IEmployeeFactory Factory { get; set; } 

    public void HireEmployee(Person person, String type, String code) 
    { 
     this.employees.Add(
      new KeyValuePair<String, IEmployee>(
       code, 
       this.Factory.Create(person, type, DateTime.Now) 
      ) 
     ); 
    } 
    public void DismissEmployee(String code) 
    { 
     this.employees.Remove(code); 
    } 
    public IEmployee GetEmployee(String code) 
    { 
     return this.employees[code]; 
    } 
    public IEmployee this[String index] 
    { 
     get { return this.employees[index]; } 
     private set { this.employees[index] = value; } 
    } 

    public Decimal TotalSalary 
    { 
     get 
     { 
      var result = 0M; 
      foreach(var item in this.employees) 
      { 
       result += item.Value.Salary; 
      } 
      return result; 
     } 
    }   
} 

最後我有一些測試代碼:

public void SalaryTest() 
    { 
     #region [Persons]    
     var SalesPerson01 = new Person 
     { 
      Birthday = new DateTime(1980, 11, 03), 
      Forename = "Corey", 
      Surname = "Black", 
      Gender = SexType.Female 
     }; 
     var SalesPerson02 = new Person 
     { 
      Birthday = new DateTime(1980, 11, 03), 
      Forename = "John", 
      Surname = "Travis", 
      Gender = SexType.Male 
     }; 
     #endregion 

     this.company.HireEmployee(SalesPerson01, "Sales", SalesPerson01.GetHashCode().ToString()); 
     ((Employee)this.company[SalesPerson01.GetHashCode().ToString()]).YearsSinceHired = 10; 

     this.company.HireEmployee(SalesPerson02, "Sales", SalesPerson02.GetHashCode().ToString()); 
     ((Employee)this.company[SalesPerson02.GetHashCode().ToString()]).YearsSinceHired = 3;    

     /////////////////////////////////////////////////////////////////// 
     ((Employee)this.company[SalesPerson01.GetHashCode().ToString()]).Subordinates.Add(
      this.company[SalesPerson02.GetHashCode().ToString()] 
     ); 

     Assert.AreEqual(1405M, this.company.TotalSalary); 
    } 

((Employee)this.company[SalesPerson01.GetHashCode().ToString()]).Subordinates.Add(this.company[SalesPerson02.GetHashCode().ToString()]);拋出NullReferenceExeption。在this.company[SalesPerson02.GetHashCode().ToString()]索引器中返回IEmployee接口但不是類實例。我對嗎?如果是這樣,我該如何解決這個問題?

+9

代碼蝙蝠俠的聖牆。把它放在少於1000行代碼的地方,我會看一看。 – RQDQ 2011-03-15 20:53:03

+0

哎呀呀。自動生成的圖表不起作用。 – 2011-03-15 20:54:51

+0

什麼與GetHashCode().... – 2011-03-15 20:55:32

回答

3

我沒有看到任何地方,要初始化的下屬成員,所以我懷疑它仍然有默認值是null空列表)。解決方法是將其初始化爲空列表構造函數:

public Manager(Person person, DateTime hiredate) : base(person, hiredate) 
{ 
    Subordinates = new List<Interface.IEmployee>(); 
} 
+0

+1爲迴應這個混亂的努力。 – 2011-03-15 20:58:36

+0

不要自動實現的屬性初始化其後臺字段嗎? – lexeme 2011-03-15 20:59:33

+2

@helicera:是 - 自動實現的屬性和普通字段自動初始化爲該類型的默認值。問題是引用類型的默認值是'null',這顯然不是你所期待的。 – 2011-03-15 21:01:33

0

看來你安排了人,但隨後鑄造員工哪些是不相關的類

0

索引返回IEmployee接口,但不一個類實例。我對嗎?

你不正確的索引器必須返回實例,從不可能的接口創建實例。

我認爲this.company [SalesPerson02.GetHashCode()。ToString()]返回null,因爲您不會將SalesPerson02實例添加到您的公司對象。

相關問題