Inconsistent accessibility Error in Program - c#

I'm currently trying to C# asp.net and this was one of my old labs that I never attended and I'm looking for help on it.
Basically I want to be able to store details of the person I input onto a webpage and then bring them up in the About page.
I keep getting the error:
Error 1: Inconsistent accessibility: field type 'System.Collections.Generic.IList<Lab5.Person>' is less accessible than field 'Lab5._Default.PresentPerson'
My code:
Class Person:
{
class Person
{
string age;
string name;
string dob;
string telNo;
string gender;
string address;
public string Age
{
get { return age; }
set { age = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string DOB
{
get { return dob; }
set { dob = value; }
}
public string TelNo
{
get { return telNo; }
set { telNo = value; }
}
public string Gender
{
get { return gender; }
set { gender = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public string enterPerson;
public Person(string name, string age, string dob, string telNo, string gender, string address)
{
Name = name;
Age = age;
DOB = dob;
TelNo = telNo;
Gender = gender;
Address = address;
}
public string PresentPerson()
{
return enterPerson = "Name: " + Name + "\n" + "Age: " + Age + "\n" + "Date of Birth: "
+ DOB + "\n" + "Telephone Number: " + TelNo + "\n" + "Gender: " + Gender + "\n" + "Address: "
+ Address;
}
}
}
Code behind the Default page:
{
public partial class _Default : Page
{
public static IList<Person> personList = new List<Person>();
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("You have successfully added a Person!");
personList.Add(new Person(TextBox1.Text, TextBox2.Text,
TextBox3.Text, TextBox4.Text, DropDownList1.Text, TextBox5.Text));
Session["Person"] = personList;
}
}
}
and code in the About page:
{
public partial class About : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session["PersonList"] != null)
{
IList<Person> personList = (List<Person>)Session["PersonList"];
foreach (Person p in personList)
{
Response.Write(string.Format("Name :{0} and Age :{1}, DOB :{2}, TelNo, :{3}, Gender :{4}, Address :{5} ", p.Name, p.Age, p.DOB, p.TelNo, p.Gender, p.Address));
Response.Write("<br/>");
}
}
}
}
}
I know that there's probably a load of issues, but I am new to C#!

Your _Default page has a list of Person field. Person is internal, but _Default is public.
This is the inconsistency - clients of _Default would have access to these Person objects when they shouldn't. To fix, make Person public:
public class Person
{
....
You could, alternatively, make the field internal or private.
private static IList<Person> personList = new List<Person>();

You need to change class Person to public class Person
If something is public like the _Default class in your example every public thing on it also needs to be public. You can't have a public thing that is in fact private.

Related

Raise events in c# - help needed

Hello I'm trying to raise an event when the Birthdate of a person is greater then the actual date.
I'm new with events and it doesn't seem to work.
Code is beneath,
namespace LibClassLuchthaven
{
public class Person
{
public DateTime Birthdate { get; set; }
public string Firstname { get; set; }
public Gender Gender { get; set; }
public string Name { get; set; }
public event EventHandler BirthdateInFuture;
public Person()
{
this.Birthdate = DateTime.Now;
this.Firstname = string.Empty;
this.Gender = Gender.unknown;
this.Name = string.Empty;
}
public Person(DateTime birthdate, string firstname, Gender gender, string name)
{
this.Birthdate = birthdate;
this.Firstname = firstname;
this.Gender = gender;
this.Name = name;
}
public void OnBirthdateInFuture()
{
if (BirthdateInFuture!=null)
{
if (this.Birthdate > DateTime.Now)
{
BirthdateInFuture(this, EventArgs.Empty);
}
}
}
public override string ToString()
{
return this.Name + ", " + this.Firstname + " - " + this.Birthdate + " ( +" + this.Gender + ")";
}
}
}
public partial class FormCrewManagement : Form
{
public Person person = new Person();
public FormCrewManagement()
{
InitializeComponent();
person.BirthdateInFuture += Person_BirthdateInFuture;
}
private void Person_BirthdateInFuture(object sender, EventArgs e)
{
MessageBox.Show("Birthdate is in the future");
}
Try Changing the Property
public DateTime Birthdate { get; set; }
to
private DateTime _birthDate;
public DateTime Birthdate
{
get {return _birthDate;}
set
{
_birthDate=value;
if(value > DateTime.Now)
BirthdateInFuture?.Invoke(this, EventArgs.Empty);
}
}
This will raise the event when Birthdate value is in future.
Philip,
there is no place in your code where the event is raised. You could create a property called BirthDate and in the setter part, raise the event. When the birthdate is changed to a future date, it would/could raise the event.
It looks like the problem may be a logical one, rather than anything to do with events. You are setting the birthday to today's date... then checking if it's later. It never will be.
public Person()
{
this.Birthdate = DateTime.Now;
if (BirthdateInFuture!=null)
{
if (this.Birthdate > DateTime.Now)
{
BirthdateInFuture(this, EventArgs.Empty);
}
}

Calling overridden method

Below shows my 3 classes: Person, Employee and SalaryEmployee.
Each class (from the right) inherits the class from the left side. E.g: SalaryEmployee inherits from Employee.
class Person
{
private string address;
private string name;
public Person(string givenName, string givenAddress)
{
name = givenName;
address = givenAddress;
}
public virtual void outputName()
{
MessageBox.Show("My name is " + name);
}
public void outputAddress()
{
MessageBox.Show("My address is " + address);
}
public void setName(string newName)
{
name = newName;
}
public void setAddress(string newAddress)
{
address = newAddress;
}
}
class Employee : Person
{
private string NINumber;
public Employee(string givenName, string givenAddress) : base(givenName, givenAddress)
{
}
public void setNINumber(string givenNumber)
{
NINumber = givenNumber;
}
public void getNINumber()
{
MessageBox.Show("My National Insurance Number is " + NINumber);
}
}
class SalaryEmployee : Employee
{
private string name;
private string address;
public SalaryEmployee(string givenName, string givenAddress) : base(givenName, givenAddress)
{
name = givenName; address = givenAddress;
}
public override void outputName()
{
MessageBox.Show("My name is " + "S_" + name);
}
}
OOP is fairly new to me and I am trying to get the hang of inheritance. The problem I am facing is I have created an object called 'PersonFive':
SalaryEmployee personFive = new SalaryEmployee("Bob", "North Pole");
// Ignore the address 'North pole' I have used as a parameter, it's just used for this example.
I am able to call the .outputName() method, the output will be:
"My name is Bob"
However, the base method is called instead of the overridden method. The output I wanted it to give me was "My name is S_Bob"
It's working for me, you might didn't post the actual code that makes the error.

How do I test a simple class?

Create an Employee class. Items to include as data members are
employee number, name, date of hire, job description, department, and
monthly salary. The class is often used to display an alphabetical
listing of all employees. Include appropriate constructors and
properties. Override the ToString ( ) method to return all data
members. Create a second class to test your Employee class.
I've created an Employee class with the proper variables, properties, and constructors, but am having trouble "testing" it through a second class. The code I have written runs without errors, but doesn't display anything (presumably the goal of the testing). Where am I going wrong in the calling section?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EmployeeProgram
{
public class EmployeeProgram
{
private int employeeNumber;
private string name;
private string hiredate;
private int monthlySalary;
private string description;
private string department;
public employee(int employeeNumber, string name, string dateOfHire, int monthlySalary, string description, string department)
{
this.employeeNumber = 456;
this.name = "Joyce";
this.hiredate = "12/15/14";
this.monthlySalary = 3200;
this.description = "Manager";
this.department = "Accounting";
}
public int EmployeeNumber
{
get
{
return employeeNumber;
}
set
{
employeeNumber = value;
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public string Hiredate
{
get
{
return hiredate;
}
set
{
hiredate = value;
}
}
public int MonthlySalary
{
get
{
return monthlySalary;
}
set
{
monthlySalary = value;
}
}
public string Department
{
get
{
return department;
}
set
{
department = value;
}
}
public string Description
{
get
{
return description;
}
set
{
description = value;
}
}
public override string ToString()
{
return "Employee ID: " + employeeNumber +
"Employee Name: " + name +
"Employee Hire Date: " + hiredate +
"Employee Monthly Salary: " + monthlySalary +
"Employee Description: " + description +
"Employee Department: " + department;
}
public void Print()
{
Console.WriteLine(this.ToString());
}
}
}
From the code you have posted, you don't call Console.WriteLine() anywhere. You have a Print method, but it won't be run until it is called. You need to create an instance of the class, then write the instance's ToString method to the console, or you can call the method Print on the instance.
In main you can do
Employee someone = new Employee(1, "John", "01/01/2016", 5000, "Engineer", "R&D");
Console.WriteLine(someone.ToString());
Console.ReadKey(); // Prevent the console from closing
In your Employee constructor, you should probably use the parameters it asks for, like this
this.employeeNumber = employeeNumber.
You should generally avoid having parameter names that match member variables/properties.
When you don't do anything special in your get and set properties, you can use auto properties
public int EmployeeNumber { get; set; }

Calling other classes from Main in C#

Have two questions assigned for homework, both of the same form, so I'll post the first one:
"Create an Employee class. Items to include as data members are
employee number, name, date of hire, job description, department, and
monthly salary. The class is often used to display an alphabetical listing of all employees. Include appropriate constructors and properties. Override the
ToString ( ) method to return all data members. Create a second class
to test your Employee class."
I've created an Employee class with the proper variables, properties, and constructors, but am having trouble "testing" it through a second class. The code I have written runs without errors, but doesn't display anything (presumably the goal of the testing). Where am I going wrong in the calling section?
Employee info section:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EmployeeProgram
{
public class employee
{
private int employeeNumber;
private string name;
private string hiredate;
private int monthlySalary;
private string description;
private string department;
public employee(int employeeNumber, string name, string dateOfHire, int monthlySalary, string description, string department)
{
this.employeeNumber = 321;
this.name = "Alex";
this.hiredate = "01/02/15";
this.monthlySalary = 2500;
this.description = "Corporate grunt";
this.department = "Sales";
}
public int EmployeeNumber
{
get
{
return employeeNumber;
}
set
{
employeeNumber = value;
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public string Hiredate
{
get
{
return hiredate;
}
set
{
hiredate = value;
}
}
public int MonthlySalary
{
get
{
return monthlySalary;
}
set
{
monthlySalary = value;
}
}
public string Department
{
get
{
return department;
}
set
{
department = value;
}
}
public string Description
{
get
{
return description;
}
set
{
description = value;
}
}
public override string ToString()
{
return "Employee ID: " + employeeNumber +
"Employee Name: " + name +
"Employee Hire Date: " + hiredate +
"Employee Monthly Salary: " + monthlySalary +
"Employee Description: " + description +
"Employee Department: " + department;
}
public void Print()
{
Console.WriteLine(this.ToString());
}
}
"Calling section"
namespace employee
{
public class employeeApp
{
public static void Main()
{
EmployeeProgram.employee Employee = new EmployeeProgram.employee(321, "Alex", "1/02/15", 2500, "Corporate grunt", "Sales");
}
}
}
You need to invoke the Print() method of EmployeeProgram.employee in the main() method.
namespace employee
{
public class employeeApp
{
public static void Main()
{
EmployeeProgram.employee Employee = new EmployeeProgram.employee(321, "Alex", "1/02/15", 2500, "Corporate grunt", "Sales");
Employee.Print();
}
}
}
But as others have pointed out, there are a lot of issues with your code:
Class name should be in Pascal casing, i.e., start with a capital letter. Hence, it should be EmployeeProgram.Employee and not EmployeeProgram.employee
Private variables generally follow Camel casing, i.e., start with small letter. Hence, it should be meployee instead of Employee in your Main() method.
You can reduce the boilerplate code in your employee class by making use to auto-properties.
Parameter dateOfHire should be a DateTime object instead of string.
Parameters like monthlySalary are generally of type decimal and not int.

C# array - "object reference not set to an instance of an object"

I am having a major issue making this work. All I need to do is make my array display.
namespace OOP_3
{
public partial class Add_Child : Form
{
public Add_Child()
{
InitializeComponent();
}
private void btnAddChild_Click(object sender, EventArgs e)
{
Mother m = new Mother();
m.MyChildren = new Child[3];
int ID = int.Parse(txtID.Text);
string FNAME = txtFname.Text;
string LName = txtLname.Text;
DateTime DOB = DateTime.Parse(txtDob.Text);
//Add children
label5.Text = m.GetMyChildrenDetails();
if (addtoarray(m,ID,FNAME,LName,DOB) == true)
{
MessageBox.Show("added", "Add Child");
}
else
{
MessageBox.Show("cannot add", "Child add - full");
}
}
public bool addtoarray(Mother m, int ID, string FNAME, string LName,DateTime DOB)
{
for (int i = 0; i < m.MyChildren.Length; i++)
{
if (m.MyChildren[i]== null)
{
m.MyChildren[i] = new Child(m); //See comment below
m.MyChildren[i].ChildId = ID;
m.MyChildren[i].FirstName = FNAME;
m.MyChildren[i].LastName = LName;
m.MyChildren[i].DateOfBirth = DOB;
return true;
}
}
return false;
}
}
}
From a code comment: This line destroys everything in the heap and recreate the array causing my to have values that will not show up in my label5.text ive been pondering researching for hours and i think iam either going insane or am just noobie at coding which iam :) please some help would be nice:)....
If needed, I will post my class's and main form up :)
public class Mother
{
//Fields
private int motherId;
private string firstName;
private string lastName;
private string mobile;
private Child[] myChildren; //mother "has a" many children
//props
public Child[] MyChildren
{
get { return myChildren; }
set { myChildren = value; }
}
public string Mobile
{
get { return mobile; }
set { mobile = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public int MotherId
{
get { return motherId; }
set { motherId = value; }
}
//constructors
//methods
//Get Mother Details
public override string ToString()
{
return motherId + ", " + firstName + ", " + lastName + ", " + mobile;
}
//AddChild
public bool AddChild(Child myChild)
{
for (int i = 0; i < myChildren.Length; i++)
{
if (myChildren[i] != null)
{
myChildren[i] = myChild;
return true;
}
}
return false;
}
//GetMyChildrenDetails
public string GetMyChildrenDetails()
{
string msg = "";
for (int i = 0; i < myChildren.Length; i++)
{
if (myChildren[i] != null)
{
msg += "\n" + myChildren[i];
}
}
return msg;
}
public class Child
{
//fields
private int childId;
private string firstName;
private string lastName;
private DateTime dateOfBirth;
private Mother myMother; //child "has a" mother
//props
public Mother MyMother
{
get { return myMother; }
set { myMother = value; }
}
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set { dateOfBirth = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public int ChildId
{
get { return childId; }
set { childId = value; }
}
//constructors
//Child cannot be created without a mother
public Child(Mother myMother)
{
this.myMother = myMother;
}
//Child cannot be created without a mother
public Child(Mother myMother, int childId)
{
this.myMother = myMother;
this.childId = childId;
}
//methods
//Get Child Details
public override string ToString()
{
return childId + ", " + firstName + ", " + lastName + ", " + dateOfBirth;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnRegister_Click(object sender, EventArgs e)
{
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void BtnAddChild_Click(object sender, EventArgs e)
{
Add_Child child = new Add_Child();
child.Show();
}
private void btnRegister_Click_1(object sender, EventArgs e)
{
//create a mother object
Mother m = new Mother();
m.MotherId = int.Parse(txtID.Text);
m.FirstName = txtFname.Text;
m.LastName = txtLname.Text;
m.Mobile = txtMobile.Text;
Giving the new child a reference to its parent object is not the cause of your issue. In summary, you state:
"to have values that will not show up in my label5.text "
This would indicate that it is either your binding that has an issue, you have not implemented INotifyPropertyChanged, or your UI updating mechanism is not working (if you are not using binding). As you haven't stated what you are using for the UI, that is about as much as I can help...
My suggestion, you may use List instead of array, because not all mothers have three children. Example code:
public static class Program
{
static void Main(string[] args)
{
Mother mother = new Mother {
FirstName = "M First", LastName = "M Last", Contact = "225632655"
};
//Add dependents
mother.AddChild(new Child{ChildID = 1, FirstName = "Child FirstName 1", LastName = "Child LastName 1"});
mother.AddChild(new Child{ChildID = 2, FirstName = "Child FirstName 2", LastName = "Child LastName 2"});
mother.AddChild(new Child{ChildID = 3, FirstName = "Child FirstName 3", LastName = "Child LastName 3"});
Console.WriteLine(mother);
//List all the mother dependents
foreach(Child c in mother.Children)
{
Console.WriteLine(c);
}
Console.ReadKey();
}
}
class Mother
{
public string FirstName {get; set;}
public string LastName {get; set;}
public string Contact {get; set;}
private List<Child> _child;
public Mother()
{
_child = new List<Child>();
}
public void AddChild(Child child)
{
_child.Add(child);
}
public List<Child> Children
{
get { return _child; }
}
public override string ToString()
{
return string.Format("{0}, {1} ({2})", LastName, FirstName, Contact);
}
}
class Child
{
public string FirstName {get; set;}
public string LastName {get; set;}
public int ChildID {get; set;}
public override string ToString()
{
return string.Format("{0} {1}, {2}", ChildID, LastName, FirstName);
}
}
I hope, this will help.

Categories

Resources