-1

I have got the data from a text file to fill in the text boxes with the data. However I am trying to get an employees salary from another class into the text box and I am struggling to do so. My first class is the employee class with this code:

public class Employee
{
    string _firstName;
    string _lastName;
    string _address;
    string _postCode;
    string _phoneNumber;
    DateTime _dateOfBirth;

    public Employee()
    {
    }

    public Employee(string firstName, string lastName, string address, string postCode, string phoneNumber, DateTime dateOfBirth)
    {
        _firstName = firstName;
        _lastName = lastName;
        _address = address;
        _postCode = postCode;
        _phoneNumber = phoneNumber;
        _dateOfBirth = dateOfBirth;
    }

    public string firstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value;
        }
    }

    public string lastName
    {
        get
        {
            return _lastName;
        }
        set
        {
            _lastName = value;
        }
    }

    public string address
    {
        get
        {
            return _address;
        }
        set
        {
            _address = value;
        }
    }

    public string postCode
    {
        get
        {
            return _postCode;
        }
        set
        {
            _postCode = value;
        }
    }

    public string phoneNumber
    {
        get
        {
            return _phoneNumber;
        }
        set
        {
            _phoneNumber = value;
        }
    }

    public DateTime dateOfBirth
    {
        get
        {
            return _dateOfBirth;
        }
        set
        {
            _dateOfBirth = value;
        }
    }

followed by the salaried class with this code:

 public class SalariedEmployee : Employee
 {
    decimal _salary;

    public SalariedEmployee(string firstName, string lastName, string 
   address, string postCode, string phoneNumber, DateTime dateOfBirth, 
 decimal salary) : base(firstName, lastName, address, postCode, phoneNumber, 
 dateOfBirth)
    {
        _salary = salary;
    }

    public decimal salary
    {
        get
        {
            return _salary;
        }
        set
        {
            _salary = value;
        }
    }
 }

this then goes onto the load method which is as follows:

public bool Load(string employeesFile)    
{
    List<string> lines = new List<string>();

    using (StreamReader reader = new StreamReader("employees.txt"))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            //Splitting the data using |
            string[] temp = line.Split('|');

            int year = Convert.ToInt32(temp[5]);
            int month = Convert.ToInt32(temp[6]);
            int day = Convert.ToInt32(temp[7]);

            //This is to populate an employees detials 
            Employee emp = new Employee
            {
                firstName = temp[0],
                lastName = temp[1],
                address = temp[2],
                postCode = temp[3],
                phoneNumber = temp[4],
                dateOfBirth = new DateTime(year, month, day)
            };

            //This class is from List, so I used the add method to add the employee.
            Add(emp);
        }
        return true;

and finally the form code:

public Salaried_Employee_Details(Employee emp)
{
    InitializeComponent();


    textBoxLastName.Text = emp.lastName;
    textBoxFirstName.Text = emp.firstName;
    textBoxAddress.Text = emp.address;
    textBoxPostCode.Text = emp.postCode;
    textBoxPhoneNumber.Text = emp.phoneNumber;
    dateTimeDateOfBirth.Text = emp.dateOfBirth.ToString();
    //textBoxSalary.Text = emp.salary;
}

with the work form here: Salary form

the format of the text file is here:

Smyth|Jack|London street, London City, London|01142325413|1990|3|21|37000

so how do I get the salaried data into the text box?

Cœur
  • 37,241
  • 25
  • 195
  • 267
rosie
  • 21
  • 5
  • how do you actually distinguish between a normal and a salaried employee in your loaded data? because you indices don't fit quite – Mong Zhu May 30 '17 at 11:46

3 Answers3

2

Looking at the split of your string into an array you either have no postal code or no number:

postCode = temp[3],
phoneNumber = temp[4],

Here are your indices of the array

Smyth|Jack|London street, London City, London|01142325413|1990|3|21|37000
  ^     ^                     ^                     ^       ^  ^  ^  ^
  |     |                     |                     |       |  |  |  |
  0     1                     2                     3       4  5  6  7

In this case 4 looks for me like a year!

If the salary is on the last position you need distinguish between a normal Employee and a SalariedEmployee In the firs case you do it like you do already and in the second case you need to create a SalariedEmployee object when loading your data:

int year = Convert.ToInt32(temp[4]);
int month = Convert.ToInt32(temp[5]);
int day = Convert.ToInt32(temp[6]);

SalariedEmployee emp = new SalariedEmployee
    {
        firstName = temp[1],
        lastName = temp[0],
        address = temp[2],
        phoneNumber = temp[3],
        dateOfBirth = new DateTime(year, month, day)
        salary = Convert.ToDecimal(temp[7]);
    };

EDIT: What you need to make this code work is a parameterless constructor in the SalariedEmployee class.

public SalariedEmployee()
{

}

or you need to use the constructor that you have written with all the parameters:

public SalariedEmployee(string firstName, string lastName, string
   address, string postCode, string phoneNumber, DateTime dateOfBirth,
 decimal salary)

which would look like this:

SalariedEmployee emp = new SalariedEmployee(temp[1], temp[0],temp[2],
                               "I don't know where your postcode is", 
                               temp[3],new DateTime(year, month, day),
                               Convert.ToDecimal(temp[7]));
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
  • Hi, I tried this but it is saying: Severity Code Description Project File Line Suppression State Error CS7036 There is no argument given that corresponds to the required formal parameter 'firstName' of 'SalariedEmployee.SalariedEmployee(string, string, string, string, string, DateTime, decimal)' – rosie May 30 '17 at 11:51
  • 1
    `SalariedEmployee` doesn't have a parameterless constructor. – David May 30 '17 at 11:56
  • @rosie You need a constructor without parameters, as David already said. I made an edit have a look – Mong Zhu May 30 '17 at 11:59
  • @MongZhu: Well, they don't *need* a parameterless constructor. They could just use the constructor they already have. Your answer is requiring one, but it's not technically necessary. – David May 30 '17 at 12:01
  • so where do I put this, I have tried but keep getting error messages? – rosie May 30 '17 at 12:10
  • @rosie what do you mean by "this" ? I guess in your `Load(string employeesFile)` method. You need to decide whether you hit a line with or without a salary. If you have a salary then you need to create a `SalariedEmployee` object otherwise you need to create a normal `Employee` object. both will work with your `Add` method, since they are both `Employee` – Mong Zhu May 30 '17 at 12:25
  • Ive put it into my load method and am still getting error, ive tried many different things to fix it – rosie May 30 '17 at 13:46
  • @MongZhu ive start from the star again and got this error: A local variable or function named 'emp' is already defined in this scope – rosie May 30 '17 at 14:05
  • @rosie that means that you should give it a different name may be `emp_salary` – Mong Zhu May 30 '17 at 14:06
  • @MongZhu yes I have done this, then do this on the form...public Salaried_Employee_Details(Employee emp, Employee emp_Salary ) { InitializeComponent(); textBoxLastName.Text = emp.lastName; textBoxFirstName.Text = emp.firstName; textBoxAddress.Text = emp.address; textBoxPostCode.Text = emp.postCode; textBoxPhoneNumber.Text = emp.phoneNumber; dateTimeDateOfBirth.Text = emp.dateOfBirth.ToString(); textBoxSalary.Text = emp_Salary.ToString(); which then comes up with the error – rosie May 30 '17 at 14:14
  • @MongZhu Severity Code Description Project File Line Suppression State Error CS7036 There is no argument given that corresponds to the required formal parameter 'emp_Salary' of 'Salaried_Employee_Details.Salaried_Employee_Details(Employee, Employee)' on this code private void buttonEdit_Click(object sender, EventArgs e) { if (listBoxEmployees.SelectedIndex >= 0) { Salaried_Employee_Details frm = new Salaried_Employee_Details(employees[listBoxEmployees.SelectedIndex]); frm.Show(); } } – rosie May 30 '17 at 14:15
  • @rosie why do you put a second parameter of type `` into the constructor of `Salaried_Employee_Details(Employee emp, Employee emp_Salary )` ?You second error comes from the point that you expect 2 parameters, but you give only one in the `buttonEdit_Click` event when creating the form. do you know how inheritance works ? you can simply cast the `Employee` to `SalariedEmployee` since `SalariedEmployee` inherits from `Employee`. – Mong Zhu May 30 '17 at 14:20
  • public Salaried_Employee_Details(Employee emp) { InitializeComponent(); textBoxLastName.Text = emp.lastName; textBoxFirstName.Text = emp.firstName; textBoxAddress.Text = emp.address; textBoxPostCode.Text = emp.postCode; textBoxPhoneNumber.Text = emp.phoneNumber; dateTimeDateOfBirth.Text = emp.dateOfBirth.ToString(); textBoxSalary.Text = emp_Salary.ToString(); like that? but I then get the error emp_salary doesnt exisit in the content? @MongZh – rosie May 30 '17 at 14:27
  • @rosie of course it does not exist. Is the Form only for showing the data of `SalariedEmployee`? then pass an `SalariedEmployee` as parameter. then you will be able to access the `salary` property – Mong Zhu May 30 '17 at 14:35
  • @MongZhu thank you, but now I am getting the error --- Error CS1503 Argument 1: cannot convert from 'HRApplication.Employee' to 'HRApplication.SalariedEmployee' private void buttonEdit_Click(object sender, EventArgs e) { if (listBoxEmployees.SelectedIndex >= 0) { Salaried_Employee_Details frm = new Salaried_Employee_Details(employees[listBoxEmployees.SelectedIndex]); frm.Show(); } } – rosie May 30 '17 at 14:46
  • @rosie you really need to research more about inheritance and casting. You are using it, so you should get more information about it how it really works.Have a look at [this post](https://stackoverflow.com/questions/16534253/c-sharp-converting-base-class-to-child-class). Basically you need to distinguish what you might have there. try `SalariedEmployee tmp = employees[listBoxEmployees.Selecte‌​dIndex] as SalariedEmployee;` then check whether the cast has worked: `if(tmp != null)` then pass `tmp` into the constructor – Mong Zhu May 30 '17 at 15:17
  • @rosie will you accept my answer only if I help you to solve all of your resulting problems and write the entire programm with you ?=! ;) – Mong Zhu May 30 '17 at 15:40
  • No not fixed it yet :( – rosie May 31 '17 at 06:48
0

There is no .salary property because the constructor is expecting an Employee:

public Salaried_Employee_Details(Employee emp)

Which doesn't have that property. However, SalariedEmployee does have that property. If the constructor needs a SalariedEmployee then simply change it to require one:

public Salaried_Employee_Details(SalariedEmployee emp)

Then you can use that property like any other:

textBoxSalary.Text = emp.salary;
David
  • 208,112
  • 36
  • 198
  • 279
  • Hi, Doing this comes up with an error on this code: private void buttonEdit_Click(object sender, EventArgs e) { if (listBoxEmployees.SelectedIndex >= 0) { Salaried_Employee_Details frm = new Salaried_Employee_Details(employees[listBoxEmployees.SelectedIndex]); frm.Show(); } } with the error been: CS1503 Argument 1: cannot convert from 'HRApplication.Employee' to 'HRApplication.SalariedEmployee' HRApplication any idea how to fix that? – rosie May 30 '17 at 18:57
  • @rosie: Well, since the constructor is expecting a `SalariedEmployee`, then you'd pass it one of those. Not just any `Employee`. It *looks like* this form requires a salaried employee just by the nature of the form itself, doesn't it? It's really up to you to define what types are required for what purposes. – David May 30 '17 at 19:22
  • sorry, How do I do that, im very confused? – rosie May 30 '17 at 19:31
  • @rosie: The error means that you're passing it an `Employee` instead of a `SalariedEmployee`. So I guess first you need to decide... Does this form *require* a `SalariedEmployee`? It has a "Salary" field, so I would expect so. But it's your design, you would be the one to decide. – David May 30 '17 at 19:34
  • ive done that like this? public Salaried_Employee_Details(SalariedEmployee emp_Salary) { InitializeComponent(); textBoxLastName.Text = emp_Salary.lastName; and this? Salaried_Employee_Details frm = new Salaried_Employee_Details(SalariedEmployee[listBoxEmployees.SelectedIndex]); but I stil get an error? – rosie May 30 '17 at 19:38
  • @rosie: That makes it *technically* require a `SalariedEmployee` object, so you would need to supply it one when calling that constructor. You need to decide if *semantically* this form should require a salaried employee. Basically, you have to decide what you want your program to do and how you want it to behave. We can resolve compiler errors in a variety of ways, which one is ideal depends on what you want the program to do. – David May 30 '17 at 19:40
  • all I want it to do is display the salary as well as all the other things firstname lastname etc etc? – rosie May 30 '17 at 19:45
  • @rosie: Ok, well, in order to display a *salary* it needs to be a *salaried employee*, right? The `Employee` class doesn't *have* a salary, only the `SalariedEmployee` class does. So if the form *needs* a salaried employee, then when you create an instance of the form you need to pass it a `SalariedEmployee` object. – David May 30 '17 at 19:48
  • sorry, so how would I do that? – rosie May 30 '17 at 19:56
  • @rosie: It would appear from the error that `employees[]` is an array of `Employee` objects. If you want your form to require a `SalariedEmployee` object, then you have to give it a `SalariedEmployee` object. Not an `Employee` object. They are two different types. – David May 30 '17 at 19:58
  • Yes, sorry. I have tried doing that but always got errors – rosie May 30 '17 at 20:03
0

Looks like there's a spot missing in the format of text file.

The string you posted

Smyth|Jack|London street, London City, London|01142325413|1990|3|21|37000

has 7 separators, which lead to an array of 8 strings, the last of them (temp[7]) being the salary. Instead, in your code it is assigned to the day property of the Employee instance.

By the way, assuming there's actually another string with the postcode formatted like this

Smyth|Jack|London street, London City, London|L12 3AS|01142325413|1990|3|21|37000

you should declare emp as a SalariedEmployee class instance instead, and I recommend using the TryParse method to check whether the salary string can be converted into decimal.

public bool Load(string employeesFile)
    {
        bool isLoaded = false;
        List<string> lines = new List<string>();

        using (StreamReader reader = new StreamReader("employees.txt"))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                //Splitting the data using |
                string[] temp = line.Split('|');

                int year = Convert.ToInt32(temp[5]);
                int month = Convert.ToInt32(temp[6]);
                int day = Convert.ToInt32(temp[7]);

                //Populating the employees details 

                decimal _salary;
                if (Decimal.TryParse(temp[8], out _salary))
                {
                    SalariedEmployee emp = new SalariedEmployee(firstName: temp[1],
                        lastName: temp[0],
                        address: temp[2],
                        postCode: temp[3],
                        phoneNumber: temp[4],
                        dateOfBirth: new DateTime(year, month, day),
                        salary: _salary)

at this point, you need to also be sure the List parameter is changed to be of SalariedEmployee type, otherwise you'll get a compiler error in the following line

                Add(emp);
                isLoaded = true;
                }
            }
            return isLoaded;
        }

at this point, in the form you just need to change the type argument and un-check the last line of code

public Salaried_Employee_Details(SalariedEmployee emp)
{
    InitializeComponent();

    textBoxLastName.Text = emp.lastName;
    textBoxFirstName.Text = emp.firstName;
    textBoxAddress.Text = emp.address;
    textBoxPostCode.Text = emp.postCode;
    textBoxPhoneNumber.Text = emp.phoneNumber;
    dateTimeDateOfBirth.Text = emp.dateOfBirth.ToString();
    textBoxSalary.Text = emp.salary;
}

Hope this might help you.

Bye! Davide.

Davide Vitali
  • 1,017
  • 8
  • 24