Reputation: 127
Im currently trying to make an addressbook application that holds some person data in an object which is then added to a list. Im currently making a method to try and list the data when prompted but the information isnt showing, does anyone know how I can go about fixing this?
namespace AddressBook
{
class Student : Person
{
public String StudentID { get; set; }
public String grade { get; set; }
public List<Student> studentList = new List<Student>();
public void addStudent(string firstName, string lastName, string address, string city, string country, string postcode, string StudentID, string grade )
{
Student student = new Student();
student.firstName = firstName;
student.lastName = lastName;
student.address = address;
student.city = city;
student.country = country;
student.postcode = postcode;
student.StudentID = StudentID;
student.grade = grade;
studentList.Add(student);
}
public void listStudentData()
{
String fname ="", lname="", add="", city="", country="", post="", id="", grd = "";
String[,] index = { { "First name: ", "Last Name: ", "Address: ", "City: ", "Country: ", "Postcode: ", "StudentID: ", "Grade: " }, { fname, lname, add, city, country, post, id, grd }, };
for (int i = 0; i < studentList.Count; i++)
{
fname = (studentList[i].firstName.ToString());
lname = (studentList[i].lastName.ToString());
add = (studentList[i].address.ToString());
city = (studentList[i].city.ToString());
country = (studentList[i].country.ToString());
post = (studentList[i].postcode.ToString());
id = (studentList[i].StudentID.ToString());
grd = (studentList[i].grade.ToString());
Console.WriteLine(index[0, i] + index[1,i]);
}
Console.WriteLine("");
}
}
}
The format I want to print out is "First Name: John" "Last Name: Smith" etc
however the current format is: "First Name: "
Any advice would be much appreciated
Upvotes: 0
Views: 1160
Reputation: 131
Posting my solution too, you might find it useful.
I see in the original sample that the base Person class is missing, providing it here:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string PostCode { get; set; }
public override string ToString()
{
return $"First name: {FirstName}, Last name: {LastName}, Address: {Address}, City: {City}, Country: {Country}, Post code: {PostCode}";
}
}
You can see that we are overriding the ToString() method to return the intended literal representation. As others have pointed out it is always better to use PascalCase notation for public properties in C# (common convention). Next comes the derived Student class:
public class Student : Person
{
public String StudentID { get; set; }
public String Grade { get; set; }
public override string ToString()
{
return $"{base.ToString()}, Student ID: {StudentID}, Grade: {Grade}";
}
}
Here we are adding the StudentID and Grade properties and again overriding the ToString() method of the Object class. The override makes use of the ToString() method of our base class which we wrote previously.
Finally, an example of printing out a list of Student objects:
static void Main(string[] args)
{
var students = new List<Student>();
students.Add(
new Student
{
FirstName = "John",
LastName = "Doe",
Address = "43 North West",
City = "Capetown",
Country = "South Africa",
PostCode = "12345",
Grade = "A+",
StudentID = Guid.NewGuid().ToString("N")
});
foreach (Student student in students)
{
Console.WriteLine(student);
}
}
And the output is:
First name: John, Last name: Doe, Address: 43 North West, City: Capetown, Country: South Africa, Post code: 12345, Student ID: 975d7bf2e80f4406b14119f8fbc3018e, Grade: A+
Upvotes: 1
Reputation: 415840
It seems a strange design choice to have the studentList
be a member of your Student
class. It belongs as a member of your program or form.
But for the specific problem, look at this line:
String[,] index = { { "First name: ", "Last Name: ", "Address: ", "City: ", "Country: ", "Postcode: ", "StudentID: ", "Grade: " }, { fname, lname, add, city, country, post, id, grd }, };
At this point, all of those attribute variables (fname
, lname
, etc) are empty strings. You later assign values to those variables:
fname = (studentList[i].firstName.ToString());
//...
However, this doesn't change the contents of the array!
I'll use just the fname
variable to explain what happened. fname
is a reference to a string object in memory. Initially it refers to an empty string. You also have the index
array that includes a number of references, and you set one of them to refer to the same empty-string object as the fname
reference. However, this is a copy of that reference. Both fname
and the index
position refer to the same object in memory, but they are independent variables. Now you assign a new value to fname
. The fname
variable refers to a different string in memory. However, the position in index
was not changed and still refers to the same empty string it had in the beginning.
To fix this, what you might want to do is overload the .ToString()
method of your Student
class (and maybe the Person
and other derived classes, as well). That would look something like this:
public override string ToString()
{
return string.Format("First name: {0}\nLast Name: {1}\nAddress: {2}\nCity: {3}\nCountry: {4}\nPostcode: {5}\nStudentID: {6}\nGrade: {7}\n",
firstName,
lastName,
address,
city,
country,
postcode,
StudentID,
grade);
}
This is useful for a number of reasons (not the least of which is helping you inspect Student objects in the debugger), but for this question it will allow you to re-write the listStudentData()
to look like this:
public void listStudentData()
{
foreach(var student in studentList)
{
Console.WriteLine(student);
}
}
In a larger, more complex program where you might need several different ways of displaying a person, instead of (or in addition to) overriding ToString()
you would add a PersonFormatter
static class that had a number of public methods for converting a Person
or Student
to a string with various outputs.
Upvotes: 1
Reputation: 406
Note: this is not the best solution, but I just want you to see what's wrong with your original code and how to correct it in case you see similar problems in the future. Please see other answers for most efficient ways to accomplish the task.
When you initialized the array, the values for all the variables you wanted to print are empty strings.
String fname ="", lname="", add="", city="", country="", post="", id="", grd = "";
What you need to do if you want to keep using your current method, is to update the variables with actual values within the for loop.
Like this:
public void listStudentData()
{
String fname ="", lname="", add="", city="", country="", post="", id="", grd = "";
String[,] index = { { "First name: ", "Last Name: ", "Address: ", "City: ", "Country: ", "Postcode: ", "StudentID: ", "Grade: " }, { fname, lname, add, city, country, post, id, grd }, };
for (int i = 0; i < studentList.Count; i++)
{
index[1,0] = studentList[i].firstName.ToString();
index[1,1] = studentList[i].lastName.ToString();
index[1,2] = studentList[i].address.ToString();
index[1,3] = studentList[i].city.ToString();
index[1,4] = studentList[i].country.ToString();
index[1,5] = studentList[i].postcode.ToString();
index[1,6] = studentList[i].StudentID.ToString();
index[1,7] = studentList[i].grade.ToString();
for (int j = 0; j < 8; j++)
{
Console.WriteLine(index[0, i] + index[1,j]);
}
}
Console.WriteLine("");
}
Upvotes: 1
Reputation: 48686
You are really over complicating things, just to list the students. It's as easy as this:
public void ListStudentData()
{
foreach (Student student in studentList)
{
Console.WriteLine("First Name: {0}", student.firstName);
Console.WriteLine("Last Name: {0}", student.lastName);
Console.WriteLine("Address: {0}", student.address);
...
...
...
}
}
Also, usually as a standard naming convention, method names should begin with a capital letter.
Upvotes: 2