Получение NullReferenceException - PullRequest
1 голос
/ 15 марта 2011

У меня такой забавный вопрос.

У меня есть следующая архитектура:

Например, класс Manager реализован так:

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

Line ((Employee)this.company[SalesPerson01.GetHashCode().ToString()]).Subordinates.Add(this.company[SalesPerson02.GetHashCode().ToString()]); бросков NullReferenceExeption. В this.company[SalesPerson02.GetHashCode().ToString()] индексатор возвращает интерфейс IEmployee, но не экземпляр класса. Я прав? И если это так, как я могу это исправить?

Ответы [ 3 ]

3 голосов
/ 15 марта 2011

Я нигде не вижу, чтобы вы инициализировали элемент Subordinates, поэтому я подозреваю, что он по-прежнему имеет значение по умолчанию null (, а не пустой список). Исправление состоит в том, чтобы инициализировать его пустым списком в конструкторе:

public Manager(Person person, DateTime hiredate) : base(person, hiredate)
{
    Subordinates = new List<Interface.IEmployee>();
}
0 голосов
/ 16 марта 2011

индексатор возвращает интерфейс IEmployee, но не экземпляр класса.Я прав?

Вы не правы, индексатор должен вернуть экземпляр, создать экземпляр из интерфейса невозможно.

Я думаю this.company [SalesPerson02.GetHashCode (). ToString ()] возвращает значение NULL, поскольку вы не добавили экземпляр SalesPerson02 в объект вашей компании.

0 голосов
/ 16 марта 2011

кажется, что вы вводите Персона, а затем переводите на Сотрудника, которые не связаны с классами

...