The code below is not returning any values. I am trying to print customer name and balance where their balance is below $0. I believe my property may not be set the right way. I am new to object oriented programming and LINQ. Any help would be appreciable.
namespace LinqExample
{
class Customer
{
private string name, phone, address;
private int balance;
public string custData;
public string Name
{
get { return name; }
set { name = value; }
}
public string Phone
{
get { return phone; }
set { phone = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public int Balance
{
get { return balance; }
set { balance = value; }
}
public Customer(string name, string phone, string address, int balance)
{
custData = name + phone + address + balance;
}
}
}
namespace LinqExample
{
class Program
{
static void Main(string[] args)
{
List<Customer> customers = new List<Customer>();
customers.Add(new Customer("Amit", "123-456-789", "123 Any Road", 25));
customers.Add(new Customer("Ajay", "571-888-1234", "1234 Any Street", 50));
customers.Add(new Customer("John", "707-123-4560", "456 John Street", -10));
customers.Add(new Customer("Ashley", "707-123-8402", "789 Ashley Street", -20));
var overdue =
from cust in customers
where cust.Balance < 0
orderby cust.Balance ascending
select new { cust.Name, cust.Balance };
foreach (var cust in overdue)
{
Console.WriteLine($"Name = {cust.Name}, Balance = {cust.Balance}");
}
}
}
}
You need to set the members values:
public Customer(string name, string phone, string address, int balance)
{
this.name = name;
this.phone = phone;
this.address = address;
this.balance = balance;
custData = name + phone + address + balance;
}
You're not setting any of your properties other than "custdata", you need to set the rest of the properties in your constructor too.
As others have stated you're not assigning any of your properties to the passed in ctor values.
Either do what Romano suggested or use an object initializer.
Assign the properties in the constructor.
public Customer(string name, string phone, string address, int balance)
{
this.name = name;
this.phone = phone;
this.address = address;
this.balance = balance;
custData = name + phone + address + balance;
}
Object Initilizer with a default ctor.
customers.Add(new Customer
{
Name = "Bill",
Phone = "555-555-5555",
Address = "2345 Some street",
Balance = "100000000"
});
As a side note, instead of using that public field "custData" try overriding the ToString method to return all of that concatenated data.
Related
I'm still kinda new into c#, and I'm currently stucked in a project. So basically I've currently have a form consisting of 5 textboxes, one checkbox and a button. When the user fills in the information, and submitting without marking the checkbox, the information is stored in a arraylist. If the user signs up as a traindriver, and marks the traindriver checkbox and submits, then a "id" need to be passed in to the arraylist, aswell as all the other information like first name and last name etc.
Currently I have a person class, which works just fine. Then I have a subclass called traindrivers, which one consists of a "id" variable, that "increments" every time a new traindrivers is signed up, since they can't have the same number. So how can I add this "id" to the "personsArrayList" if the person that are signed up, are marked as a traindriver?
Form
I've tried to use the procedure as I've used when new Persons are added. But for some reason, I couldn't find the varaibles which contains the id.
public class Persons
{
//instance variables
private string firstname;
private string lastname;
private string email;
private int age;
//constructor
public Persons(string firstname, string lastname, string email, int age)
{
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
this.age = age;
}
public string FirstName
{
get { return firstname; }
set { firstname = value; }
}
public string LastName
{
get { return lastname; }
set { lastname = value; }
}
public string Email
{
get { return email; }
set { email = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public override string ToString()
{
return FirstName + " " + LastName + " - " + Email + " - " + Age + ".";
}
}
public class Traindrivers : Persons
{
protected int id;
protected static int mycounter;
public Traindrivers(int id, string firstname, string lastname, string email, int age) : base(firstname, lastname, email, age)
{
mycounter++;
id = mycounter;
}
public int LicensNumber
{
get { return id; }
set { id = value; }
}
public override string ToString()
{
return LicensNumber + FirstName + LastName + Email + Age;
}
}
----------- aspx page ---------
protected void Button1_Click(object sender, EventArgs e)
{
Persons p1 = new Persons(TextBoxFirstName.Text, TextBoxLastName.Text, TextBoxEmail.Text, Convert.ToInt32(TextBoxAge.Text));
personsArrayList.Add(p1);
//Session["trainpersons"] = personsArrayList;
}
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
// When the checkbox is marked, add "id" to the arraylist
}
protected void ShowButton_Click(object sender, EventArgs e)
{
ListBox1.Items.Clear();
for (int i = 0; i < personsArrayList.Count; i++)
{
ListBox1.Items.Add(personsArrayList[i].ToString());
Console.WriteLine(i);
}
}
}
protected void trainBtn_Click(object sender, EventArgs e)
{
ListBox1.Items.Clear();
for (int i = 0; i < traindriversArrayList.Count; i++)
{
ListBox1.Items.Add(traindriversArrayList[i].ToString());
}
}
The expected result is to add "id" whenever is it a traindriver, that signs up. And it is of course expected to go into the personsArrayList.
ok based on this new edit, everything will be ok with few minor changes.
first of all you do not need any counter, static id will be enough and because you want to increment that id, it should be initialized. and since it is going to work automatically, no need to take id as an argument
public class Traindrivers : Persons
{
protected int id=0;
// ^^
protected static int mycounter=0;
public Traindrivers(/*int id,*/ string firstname, string lastname, string email, int age) : base(firstname, lastname, email, age)
// ^^^^^^^^^
{
mycounter++;
id = mycounter;
}
public int LicensNumber
{
get { return id; }
set { id = value; }
}
public override string ToString()
{
return LicensNumber + FirstName + LastName + Email + Age;
}
}
when you want to use it, in Button1_Click method, first you check if that checkbox is checked or not, then behave based on that, like this:
protected void Button1_Click(object sender, EventArgs e){
if(CheckBox1.checked==true){//information is about a traindriver
Traindrivers t1 = new Traindrivers (TextBoxFirstName.Text, TextBoxLastName.Text, TextBoxEmail.Text, Convert.ToInt32(TextBoxAge.Text));
traindriversArrayList.Add(t1);
}
else{//information in textboxes is not about traindriver
Persons p1 = new Persons(TextBoxFirstName.Text, TextBoxLastName.Text, TextBoxEmail.Text, Convert.ToInt32(TextBoxAge.Text));
personsArrayList.Add(p1);
}
}
I'm trying to return multiple parameters, if that's how to word it. I'm trying to "translate" Python code into C#.
I'm actually not quite sure what exact term I'm searching for, but I know how to do it in Python so I'll just show my code.
class Staff
{
public String name;
public int age;
/* Now in Python, you can easily write this following, but I have no
idea how this works in C#. I basically want to return all the values
for each employee in the "Staff" class */
def desc(self):
desc_str = "%s is %s years old." % (self.name, self.age)
return desc_str
}
class Program
{
public static void Main()
{
Staff Jack = new Staff();
Jack.name = "Jack";
Jack.age = 40;
Staff Jill = new Staff();
Jill.name = "Jill";
Jill.age = 50;
Console.WriteLine(Jack.desc());
Console.WriteLine(Jill.desc());
Console.ReadKey();
}
}
EDIT: I figured out that what I was searching for was get, set and ToString() and will look into it now.
The code I've translated looks like the following now:
class Staff
{
private string name;
private int age;
private string yearsold = " years old.";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public string YearsOld
{
get
{
return yearsold;
}
set
{
yearsold = value;
}
}
public override string ToString()
{
return "Employee " + Name + " is " + Age + YearsOld;
}
}
class TestPerson
{
static void Main()
{
// Create a new Person object:
Staff person = new Staff();
person.Name = "Jack";
person.Age = 40;
Console.WriteLine(person);
person.Name = "Jill";
person.Age = 50;
Console.WriteLine(person);
Console.ReadKey();
}
}
Since you have a class, you can override the ToString function and use the string.Format function like so:
class Staff
{
public string name;
public int age;
public Staff(string _name, int _age)
{
this.name = _name;
this.age = _age;
}
public override string ToString()
{
return string.Format("{0} is {1} years old.", this.name, this.age);
}
}
Then to print:
Staff Jack = new Staff("Jack", 40);
Console.WriteLine(Jack); // implicitly calls Jack.ToString()
Hope that helps.
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:
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?
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]));
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;
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.
I have a form (Edit) with some textbox controls as private members with public properties that I want to access from another class (PatientService) and I can't figure out how to overcome the "textbox does not exist in the current context" errors for the 8 controls I am trying to access. Also, is passing these values through the constructor a good way of doing this? I cannot have any other part of my project aside from the PatientService class interacting with the database. Thanks and the textboxes in question are in bold.
public partial class Edit : XtraForm
{
private string patientID;
private string firstName;
private string lastName;
private string address;
private string city;
private string state;
private string zipCode;
private string phone;
public Edit(string PatientID, string FirstName, string LastName, string Address, string City, string State, string ZipCode, string Phone)
{
InitializeComponent();
patientID = txtPatientID.Text;
firstName = txtFirstName.Text;
lastName = txtLastName.Text;
address = txtAddress.Text;
city = txtCity.Text;
state = txtState.Text;
zipCode = txtZipCode.Text;
phone = txtPhone.Text;
}
public string PatientID
{
get { return patientID; }
set { patientID = value; }
}
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 City
{
get { return city; }
set { city = value; }
}
public string State
{
get { return state; }
set { state = value; }
}
public string ZipCode
{
get { return txtZipCode.Text; }
set { txtZipCode.Text = value; }
}
public string Phone
{
get { return phone; }
set { phone = value; }
}
public void CreatePatient()
{
//SAConnection conn = new SAConnection("dsn={SQL Anywhere 10};uid=dba;pwd=sql;databasefile=C:\\Users\\Kbaker1\\Desktop\\Training1.db;");
//SACommand cmd = new SACommand("INSERT INTO patient(patient_id, first_name, last_name, address, city, state, zipcode, phone) VALUES(); ");
using (SAConnection conn = new SAConnection())
{
conn.ConnectionString = "dsn={SQL Anywhere 10};uid=dba;pwd=sql;databasefile=C:\\Users\\Kbaker1\\Desktop\\Training1.db;";
conn.Open();
using (SACommand cmd = conn.CreateCommand())
{
cmd.CommandText =
"insert into patient(\n" +
" patient_id,\n" +
" first_name,\n" +
" last_name,\n" +
" address,\n" +
" city,\n" +
" state,\n" +
" zipcode,\n" +
" phone)\n" +
" values(\n" +
" #prm_patient_id,\n" +
" #prm_first_name,\n" +
" #prm_last_name,\n" +
" #prm_address,\n" +
" #prm_city,\n" +
" #prm_state,\n" +
" #prm_zipcode,\n" +
" #prm_phone)";
cmd.Parameters.Add("#prm_patient_id", SADbType.VarChar, 80).Value = **txtPatientID.Text**;
cmd.Parameters.Add("#prm_first_name", SADbType.VarChar, 80).Value = **txtFirstName.Text**;
cmd.Parameters.Add("#prm_last_name", SADbType.VarChar, 80).Value = **txtLastName.Text**;
cmd.Parameters.Add("#prm_address", SADbType.VarChar, 80).Value = **txtAddress.Text**;
cmd.Parameters.Add("#prm_city", SADbType.VarChar, 80).Value = **txtCity.Text**;
cmd.Parameters.Add("#prm_state", SADbType.VarChar, 80).Value = **txtState.Text**;
cmd.Parameters.Add("#prm_zipode", SADbType.VarChar, 80).Value = **txtZipCode.Text**;
cmd.Parameters.Add("#prm_phone", SADbType.VarChar, 80).Value = **txtPhone.Text**;
cmd.ExecuteNonQuery();
}
}
}
Ok, so I'm still a little confused. I made the Patient class and instantiated it in the Edit form just like this.
public Patient pat;
public Edit(Patient patient)
{
InitializeComponent();
pat = patient;
}
I'm trying to get it to when I click on an "OK" button, the textbox controls are inserted into the database via a CreatePatient method in the PatientService class.
Here is the method from the Edit Form that invokes the CreatePatient method in the PatientService class:
private void btnOK_Click(object sender, EventArgs e)
{
PatientService ps = new PatientService();
ps.CreatePatient();
}
My Patient class looks like:
public class Patient
{
List<Patient> patList = new List<Patient>();
private string patientID;
private string firstName;
private string lastName;
private string address;
private string city;
private string state;
private string zipCode;
private string phone;
private int classificationID;
protected object Dispose;
public Patient(string PatientID, string FirstName, string LastName, string Address, string City, string State, string ZipCode, string Phone, int ClassificationID)
{
this.patientID = PatientID;
this.firstName = FirstName;
this.lastName = LastName;
this.address = Address;
this.city = City;
this.state = State;
this.zipCode = ZipCode;
this.phone = Phone;
this.classificationID = ClassificationID;
}
public string PatientId
{
get { return patientID; }
set { patientID = value; }
}
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 City
{
get { return city; }
set { city = value; }
}
public string State
{
get { return state; }
set { state = value; }
}
public string ZipCode
{
get { return zipCode; }
set { zipCode = value; }
}
public string Phone
{
get { return phone; }
set { phone = value; }
}
public int ClassificationID
{
get { return classificationID; }
set { classificationID = value; }
}
public Patient(string PatientID)
{
this.patientID = PatientID;
}
public Patient()
{
}
}
}
So considering I am no longer passing values through the Edit constructor like in the beginning, how would I make use of the Patient class to get the textbox values sent to the database?
You do not need to access your controls from other form, or class.
Since you have public properties, you can access to it from parent form:
Edit form = new Edit(patientId, ...);
//after using form
string patientId = form.PatientID;
Better option is wrap your fields into a single object, like entity
public class Patient
{
private string patientID;
private string firstName;
private string lastName;
private string address;
private string city;
private string state;
private string zipCode;
private string phone;
//put here your properties
}
Use it in your Edit form
public partial class Edit : XtraForm
{
public Patient Patient;
public Edit() //empty constructor if you want to pass data manually via property
{
InitializeComponent();
}
public Edit(Patient patient)
{
InitializeComponent();
Patient = patient;
}
//full code here
}
You can always keep actual data in Patient object using EditValueChanged event form your text boxes (As far as I know you are using DevExpress controls, like XtraForm). For example:
private void txtPatientID_EditValueChanged(object sender, EventArgs e)
{
Patient.patientId = txtPatientID.Text;
}
You need to pass your form class to PatientService
For example:
public class PatientService
{
//your code
public Edit EditForm{get;set;}
}
Now you can pass Edit to PatientService:
somewhere:
var svc = new PatientService();
svc.EditForm = existEditForm;
You can access tour edit form from patient service now. Something like this:
EditForm.PatientId = "0";
In my program I have a list of marks and a dictionary which stores the studentId. I want that the user enters the studentId and according to that id it will point to the list of marks. I think I am implementing it incorrectly. Can someone help me in implementing it. Thanks
public class Student() {
private string name;
private string surname;
private string dob;
private string address;
private int id;
public Student()
{
}
public Student(string year,string name, string surname, string dob, string address)
{
this.name = name;
this.surname = surname;
this.dob = dob;
this.address = address;
this.year = year;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Surname
{
get { return surname; }
set { surname = value; }
}
public string DOB
{
get { return dob; }
set { dob = value; }
}
public string Addr
{
get { return address; }
set { address = value; }
}
public int Id
{
get { return id; }
set { id = value; }
}
private string year;
public string Year
{
get { return year; }
set { year = value; }
}
public Student(string s)
{
string[] splitted = s.Split(',');
name = splitted[0];
surname = splitted[1];
dob = splitted[2];
address = splitted[3];
// id = splitted[4];
}
public Dictionary<int,List<Marks>> dictionary= new Dictionary<int,List<Marks>>();
public List<Marks> Mathematics = new List<Marks>();
public List<Marks> English = new List<Marks>();
public List<Marks> Maltese = new List<Marks>();
public List<Marks> ReligiousStudies = new List<Marks>();
public List<Marks> SocialStudies = new List<Marks>();
public Dictionary<int, List<Marks>> dictionar = new Dictionary<int, List<Marks>>();
public void AddMarks(int hyexam, int anexam)
{
{
Console.WriteLine("enter id of student to input marks to:");
string id = Console.ReadLine();
if (dictionar.ContainsKey(Id).Equals(id))
{
Mathematics.Add(new Marks(hyexam, anexam));
English.Add(new Marks(hyexam, anexam));
Maltese.Add(new Marks(hyexam, anexam));
ReligiousStudies.Add(new Marks(hyexam, anexam));
SocialStudies.Add(new Marks(hyexam, anexam));
dictionar.Add(id, (Mathematics)); //dont know how to implement it
}
else
{
Console.WriteLine("id not found");
}
}
}
public class Marks
{
private int hyexam;
private int anexam;
private string id;
public int HYEXAM
{
get { return hyexam; }
set { hyexam = value; }
}
public int ANEXAM
{
get { return anexam; }
set { anexam = value; }
}
public string Id
{
get { return id; }
set { id = value; }
}
public Marks(int hyexam, int anexam)
{
this.hyexam = hyexam;
this.anexam = anexam;
}
public Marks(string id)
{
this.id = id;
}
public double OverallExam()
{
return (0.4 * hyexam) + (0.6 * anexam);
}
}
}
I'd say the main problem is your modelling. You've included the Dictionary<int, List<Marks>> as a field within Student. That means that each Student object has a dictionary. That makes no sense - because the key for the dictionary is meant to be the student ID, right?
It probably makes sense for each Student object to the lists of marks as you've currently got (although not as public fields, IMO). Given that information, do you really need a Dictionary going to the marks at all? Wouldn't it be cleaner to have a Dictionary<int, Student> somewhere (not in the Student class - maybe in a School class?) mapping each student ID to a Student, and you can get the marks from the Student?
Think hard about what you're trying to achieve, and where the data really belongs. In my experience, when you've got the data modelling right, the code usually follows in a clean way.
(I'd also question your Marks class, both in terms of name and design. What are those properties meant to represent? Isn't it really a single mark in an exam? Perhaps ExamResult would be clearer? Does it really need to be mutable?)
I'd agree with Jon that this is definitely a modeling issue (based on the OP's other posts). If you're new to object oriented programming, the first thing you need to do is determine what objects you'll need to create to answer the problem.
What is a Student? A student has a name, id, dob, class year, etc. For every attribute a student has, you need to set up a field or property.
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DoB { get; set; }
... etc ...
}
What is a Mark? From your descriptions, a Mark has a subject, a mid-exam score, and an annual-exam score.
public class Mark
{
public string Subject { get; set; }
public int MidScore { get; set; }
public int FinalScore { get; set; }
}
What is the relationship between a Student and a Mark? A student has a list of marks associated with them. This is best described with a List<> object.
public class Student() // continued
{
public List<Mark> Marks { get; set; }
}
Once you have the basics set up for your objects, it will be easier to filter out what you DON'T need, and make it much easier to answer your question. :)
My proposal:
Your "Mark" class must have something that identifies the subject (could be an enum called Subject, or an string, or an int with the ID of the subject if you have it stored in database)
Then you could have:
Console.WriteLine("enter id of student to input marks to:");
string id = Console.ReadLine();
var marks = new Dictionary<int, List<Mark>>();
if (UserExists(id))
{
Console.WriteLine("mark for subject1:");
string s1 = Console.ReadLine();
Console.WriteLine("mark for subject2:");
string s2 = Console.ReadLine();
var list = new List<Mark>();
list.Add(new Mark { Subject = SubjectEnum.Subject1, Value = Convert.ToDecimal(s1), });
list.Add(new Mark { Subject = SubjectEnum.Subject2, Value = Convert.ToDecimal(s2), });
marks.Add(Convert.ToInt32(id), list)
}
else
{
Console.WriteLine("id not found");
}
Hope this helps.