【问题标题】:List items added from one class not accessible from another class列出从一个类添加的项目不能从另一个类访问
【发布时间】:2021-12-11 18:16:02
【问题描述】:

我正在编写一个程序,它使用列表来存储员工数据,遵循 SOLID 原则,我试图将尽可能多的功能从主类移到他们自己的类中。我有一个存储库类,它列出了初始列表值,并包含读取和创建方法来访问和编辑列表。我的问题是我的新班级无法访问随后添加到列表中的任何内容,并且只能在启动时看到 intail 数据。

这是我的回购类:

public class Repository
{
private List<EmployeeData> myEmployeeData = new List<EmployeeData>()
{
    new EmployeeData()
    {
        EmployeeID = 1,
        FName = "Joe",
        LName = "Bloggs",
        isPermanent = true,
        Salaryint = 40000,
        Bonusint = 5000,
        DayRateint = null,
        WeeksWorkedint = null
    },

    new EmployeeData()
    {
        EmployeeID = 2,
        FName = "John",
        LName = "Smith",
        isPermanent = true,
        Salaryint = 45000,
        Bonusint = 2500,
        DayRateint = null,
        WeeksWorkedint = null
    },

    new EmployeeData()
    {
        EmployeeID = 3,
        FName = "Clare",
        LName = "Jones",
        isPermanent = false,
        Salaryint = null,
        Bonusint = null,
        DayRateint = 350,
        WeeksWorkedint = 40
    }
};

public EmployeeData Create(int IDcount, string fname, string lname, bool isPerm, int? Salary, int? Bonus, int? DayRate, int? WeeksWorked)
{
    var createEmployee = new EmployeeData()
    {
        EmployeeID = IDcount,
        FName = fname,
        LName = lname,
        isPermanent = isPerm,
        Salaryint = Salary,
        Bonusint = Bonus,
        DayRateint = DayRate,
        WeeksWorkedint = WeeksWorked
    };
    myEmployeeData.Add(createEmployee);
    return createEmployee;
}

public IEnumerable<EmployeeData> ReadAll()
{
    return (myEmployeeData);
}

public EmployeeData Read(int employeeID)
{
    return myEmployeeData[employeeID];
}

public EmployeeData Update(int employeeID, string fname, string lname, bool isPerm, int? Salary, int? Bonus, int? DayRate, int? WeeksWorked)
{
    var x = Read(employeeID);
    x.FName = fname;
    x.LName = lname;
    x.isPermanent = isPerm;
    x.Salaryint = Salary;
    x.Bonusint = Bonus;
    x.DayRateint = DayRate;
    x.WeeksWorkedint = WeeksWorked;
    return x;
}

public bool Delete(int employeeID)
{
    myEmployeeData.RemoveAt(employeeID);
    return true;
}
}

这是我的新课程,无法访问新创建的项目:

public class Calculator : Repository
{
public double AnnualPayAfterTax;
public double AnnualPay;

public double CalculateEmployeePay(int employeeID)
{
    bool EmploymentStatus = Read(employeeID).isPermanent;
    if (EmploymentStatus == true) 
    { 
        int Salary = (int)Read(employeeID).Salaryint;
        int Bonus = (int)Read(employeeID).Bonusint;
        AnnualPay = Salary + Bonus;
    }
    else {
        int DayRate = (int)Read(employeeID).DayRateint;
        int WeeksWorked = (int)Read(employeeID).WeeksWorkedint;
        AnnualPay = (DayRate * 5) + WeeksWorked;
    }
    if (AnnualPay < 12570) { AnnualPayAfterTax = AnnualPay; }
    if (AnnualPay > 12570) { AnnualPayAfterTax = (AnnualPay - 12570) * 0.2; }
    return (AnnualPayAfterTax);
}
}

这是调用这两个类的主要方法的一部分,注意 read() 在这个类中对于新添加的列表项工作正常。

                    bool CalLoop = false;
                while (CalLoop == false)
                {
                    Console.Clear();
                    Console.WriteLine("CALCULATE ANNUAL PAY\n");
                    Console.WriteLine(string.Concat(re.ReadAll()));
                    Console.Write("\nSelect ID of Employee:  ");
                    string Input = Console.ReadLine();
                    bool valid = int.TryParse(Input, out Output);
                    if (valid)
                    {
                        int selectedID = Output;
                        selectedID = selectedID - 1;
                        bool CheckID = (selectedID <= IDcount);
                        if (CheckID)
                        {
                            Console.WriteLine("Employee Name:  " + re.Read(selectedID).FName + " " + re.Read(selectedID).LName);
                            Console.WriteLine("Employment Type:  " + re.Read(selectedID).isPermanent);
                            Console.WriteLine("Annual Pay after Tax:  £" + cal.CalculateEmployeePay(selectedID));
                        }
                        else
                        {
                            Console.WriteLine("Invaild ID.");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Invaild ID.");
                    }
                    CalLoop = true;
                }

知道为什么我的新班级看不到任何新添加到列表中的内容吗?我认为列表在整个运行时动态更新?我错过了什么吗?

感谢任何帮助或 cmets,所以提前谢谢你!

【问题讨论】:

    标签: c# list class inheritance


    【解决方案1】:

    你有两个班级:

    public class Repository
    {
        public List<EmployeeData> myEmployeeData = new List<EmployeeData>();
    }
    
    public class Calculator : Repository
    { }
    

    当这两个类被实例化时,你可以看到它不共享同一个列表:

    var rep = new Repository();
    var cal = new Calculator();
    
    if(object.ReferenceEquals(rep.myEmployeeData, cal.myEmployeeData))
    {
        Console.WriteLine("Repository and Calucaltor share the same liste.")
    }
    else
    {
        Console.WriteLine("Repository and Calucaltor don't share the same liste.")
    }
    

    班级就像建造建筑物的计划。 例如,“BaseBuilding”计划有一个接待处和一个洗手间。 以及从“BaseBuilding”计划扩展(继承)并添加一些办公室来工作的“OfficeBuilding”计划

    接下来,您按照“BaseBuilding”计划建造一座建筑物,并按照“OfficeBuilding”计划建造另一座建筑物。 在这种情况下,您需要建造两个接待处和洗手间(一个由建筑物组成)。

    实例化RepositoryCalculator 时也是如此。 这会创建两个不同的对象,每个对象都有自己的列表。 更多信息请参见inheritance的官方文档;

    但这是真正的问题。当类 A 继承自类 B 时,您可以将 B 替换为 A。 在您的情况下,Calculator 继承自 Repository,然后您可以将 Repository 替换为 Calculator

    I use the repository to read employee's informations.
    I use the calculator to read employee's informations.
    

    第一句话很清楚,但第二句话……听起来很奇怪。 这是因为这打破了第三个 SOLID 原则(Liskov 替换)。

    还有为什么计算器可以读取员工信息? 这是存储库检索员工信息的责任。 计算器应该只做计算。 这违反了第一个 SOLID 原则(单一责任)。

    如果你想遵循 SOLID 原则,那么我建议你 to avoid inheritance and prefer the composition

    在你的情况下:

    class Calculator
    {
        private readonly Repository _repository;
    
        public Calculator(Repository repository)
        {
            _repository = repository;
        }
    
        public double CalculateEmployeePay(int employeeID)
        {
            bool EmploymentStatus = _repository.Read(employeeID).isPermanent;
            ...
        }
    }
    

    所以计算器只计算,存储库只管理员工。

    【讨论】:

      【解决方案2】:

      private List&lt;EmployeeData&gt; myEmployeeData = new List&lt;EmployeeData&gt;()private ... 将其更改为 protected 以便继承的类可以访问它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 2012-05-18
        • 1970-01-01
        • 2014-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多