Address book console application
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
8
down vote
favorite
I have been taking some C# online courses the last couple of weeks in order to learn programming. Since I dont have any friends that are programming I found it hard to get feedback / reviews on the code I'm writing. Sure the code is running, but how about the code quality?
About the project
I have created a simple Address Book (console application) based on four classes:
- Main
- AdressBook
- Person
- WriteAndReadToFile
The application has the following abilities:
- Store friends
- Update friend information
- Remove user
- Show all users
- When adding/update/remove user it should be stored on a txt-file (which is loaded when the program start).
For simplicity I only added only name and adress in the application, there is also very bad data-input validation (focusing in learing OOP). Regarding the update function I am aware that it will update everything wich have a match on firstName.
Questions
- Am I using OOP in a correct way?
- I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Code
Main
class Program
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
ab.CreateUser();
break;
case "2":
ab.UpdateUserInformation();
break;
case "3":
ab.RemovePersonFromList();
break;
case "4":
ab.ShowAllPersonsInList();
break;
case "x":
ProgramIsRunning = false;
break;
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine("#1 Create new user");
Console.WriteLine("#2 Edit user information");
Console.WriteLine("#3 Delete existing user");
Console.WriteLine("#4 Show all users in adressBook");
private static AdressBook StartProgram()
AdressBook ab = new AdressBook();
//Start program by loading saved users from txt-file
WriteAndReadToFile writer = new WriteAndReadToFile();
writer.ReadFromFile(ab);
return ab;
Person
class Person
public string FirstName get; set;
public string LastName get; set;
public string Adress get; set;
public Person(string firstName, string lastName, string adress)
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
}
AdressBook
class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
wtf.WriteUserToFile(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person) => AdressBookList.Add(person);
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
//Show all Persons in AdressBookList
public void ShowAllPersonsInList()
foreach (var person in AdressBookList)
Console.WriteLine("FirstName: 0, LastName: 1, Adress: 2", person.FirstName, person.LastName, person.Adress);
public void UpdateUserInformation()
Console.WriteLine("Which information do you want to update?");
Console.WriteLine("#1: Firstname, #2: Lastname, 3# Adress");
var userOption = Console.ReadLine();
Console.WriteLine("Enter firstname on existing user to be updated");
var oldFirstName = Console.ReadLine();
UpdateUserFunction(userOption, oldFirstName);
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
if(userOption == "1")
Console.WriteLine("Enter a new first Name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.FirstName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if (userOption == "2")
Console.WriteLine("Enter a new last name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.LastName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if(userOption == "3")
Console.WriteLine("Enter a new adress");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.Adress = newValue;
wtf.UpdateUserOnFile(adressBookList);
WriteToFile
class WriteAndReadToFile
private readonly string UserTextFile = ConfigurationManager.AppSettings["textFileName"];
public void WriteUserToFile(Person person)
using (StreamWriter sw = new StreamWriter(UserTextFile, true))
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
public void ReadFromFile(AdressBook ab)
string textLine;
try
using (StreamReader sr = new StreamReader(UserTextFile))
while ((textLine = sr.ReadLine()) != null)
string userInformation = textLine.Split(',');
Person p = new Person(userInformation[0], userInformation[1], userInformation[2]);
ab.AdressBookList.Add(p);
catch (FileNotFoundException fnf)
Console.WriteLine("File does not exist " + fnf);
catch (Exception e)
Console.WriteLine("Something went wrong" + e);
public void UpdateUserOnFile(List<Person> adressBookList)
// Remove old row
using (StreamWriter sw = new StreamWriter(UserTextFile))
sw.Flush();
foreach (var person in adressBookList)
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
c# beginner object-oriented
add a comment |Â
up vote
8
down vote
favorite
I have been taking some C# online courses the last couple of weeks in order to learn programming. Since I dont have any friends that are programming I found it hard to get feedback / reviews on the code I'm writing. Sure the code is running, but how about the code quality?
About the project
I have created a simple Address Book (console application) based on four classes:
- Main
- AdressBook
- Person
- WriteAndReadToFile
The application has the following abilities:
- Store friends
- Update friend information
- Remove user
- Show all users
- When adding/update/remove user it should be stored on a txt-file (which is loaded when the program start).
For simplicity I only added only name and adress in the application, there is also very bad data-input validation (focusing in learing OOP). Regarding the update function I am aware that it will update everything wich have a match on firstName.
Questions
- Am I using OOP in a correct way?
- I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Code
Main
class Program
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
ab.CreateUser();
break;
case "2":
ab.UpdateUserInformation();
break;
case "3":
ab.RemovePersonFromList();
break;
case "4":
ab.ShowAllPersonsInList();
break;
case "x":
ProgramIsRunning = false;
break;
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine("#1 Create new user");
Console.WriteLine("#2 Edit user information");
Console.WriteLine("#3 Delete existing user");
Console.WriteLine("#4 Show all users in adressBook");
private static AdressBook StartProgram()
AdressBook ab = new AdressBook();
//Start program by loading saved users from txt-file
WriteAndReadToFile writer = new WriteAndReadToFile();
writer.ReadFromFile(ab);
return ab;
Person
class Person
public string FirstName get; set;
public string LastName get; set;
public string Adress get; set;
public Person(string firstName, string lastName, string adress)
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
}
AdressBook
class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
wtf.WriteUserToFile(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person) => AdressBookList.Add(person);
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
//Show all Persons in AdressBookList
public void ShowAllPersonsInList()
foreach (var person in AdressBookList)
Console.WriteLine("FirstName: 0, LastName: 1, Adress: 2", person.FirstName, person.LastName, person.Adress);
public void UpdateUserInformation()
Console.WriteLine("Which information do you want to update?");
Console.WriteLine("#1: Firstname, #2: Lastname, 3# Adress");
var userOption = Console.ReadLine();
Console.WriteLine("Enter firstname on existing user to be updated");
var oldFirstName = Console.ReadLine();
UpdateUserFunction(userOption, oldFirstName);
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
if(userOption == "1")
Console.WriteLine("Enter a new first Name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.FirstName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if (userOption == "2")
Console.WriteLine("Enter a new last name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.LastName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if(userOption == "3")
Console.WriteLine("Enter a new adress");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.Adress = newValue;
wtf.UpdateUserOnFile(adressBookList);
WriteToFile
class WriteAndReadToFile
private readonly string UserTextFile = ConfigurationManager.AppSettings["textFileName"];
public void WriteUserToFile(Person person)
using (StreamWriter sw = new StreamWriter(UserTextFile, true))
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
public void ReadFromFile(AdressBook ab)
string textLine;
try
using (StreamReader sr = new StreamReader(UserTextFile))
while ((textLine = sr.ReadLine()) != null)
string userInformation = textLine.Split(',');
Person p = new Person(userInformation[0], userInformation[1], userInformation[2]);
ab.AdressBookList.Add(p);
catch (FileNotFoundException fnf)
Console.WriteLine("File does not exist " + fnf);
catch (Exception e)
Console.WriteLine("Something went wrong" + e);
public void UpdateUserOnFile(List<Person> adressBookList)
// Remove old row
using (StreamWriter sw = new StreamWriter(UserTextFile))
sw.Flush();
foreach (var person in adressBookList)
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
c# beginner object-oriented
1
Welcome to Code Review! I hope you get some good answers. Your code already looks cleaner than a lot that I wrote when I started.
â Gerrit0
May 1 at 20:13
add a comment |Â
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I have been taking some C# online courses the last couple of weeks in order to learn programming. Since I dont have any friends that are programming I found it hard to get feedback / reviews on the code I'm writing. Sure the code is running, but how about the code quality?
About the project
I have created a simple Address Book (console application) based on four classes:
- Main
- AdressBook
- Person
- WriteAndReadToFile
The application has the following abilities:
- Store friends
- Update friend information
- Remove user
- Show all users
- When adding/update/remove user it should be stored on a txt-file (which is loaded when the program start).
For simplicity I only added only name and adress in the application, there is also very bad data-input validation (focusing in learing OOP). Regarding the update function I am aware that it will update everything wich have a match on firstName.
Questions
- Am I using OOP in a correct way?
- I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Code
Main
class Program
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
ab.CreateUser();
break;
case "2":
ab.UpdateUserInformation();
break;
case "3":
ab.RemovePersonFromList();
break;
case "4":
ab.ShowAllPersonsInList();
break;
case "x":
ProgramIsRunning = false;
break;
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine("#1 Create new user");
Console.WriteLine("#2 Edit user information");
Console.WriteLine("#3 Delete existing user");
Console.WriteLine("#4 Show all users in adressBook");
private static AdressBook StartProgram()
AdressBook ab = new AdressBook();
//Start program by loading saved users from txt-file
WriteAndReadToFile writer = new WriteAndReadToFile();
writer.ReadFromFile(ab);
return ab;
Person
class Person
public string FirstName get; set;
public string LastName get; set;
public string Adress get; set;
public Person(string firstName, string lastName, string adress)
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
}
AdressBook
class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
wtf.WriteUserToFile(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person) => AdressBookList.Add(person);
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
//Show all Persons in AdressBookList
public void ShowAllPersonsInList()
foreach (var person in AdressBookList)
Console.WriteLine("FirstName: 0, LastName: 1, Adress: 2", person.FirstName, person.LastName, person.Adress);
public void UpdateUserInformation()
Console.WriteLine("Which information do you want to update?");
Console.WriteLine("#1: Firstname, #2: Lastname, 3# Adress");
var userOption = Console.ReadLine();
Console.WriteLine("Enter firstname on existing user to be updated");
var oldFirstName = Console.ReadLine();
UpdateUserFunction(userOption, oldFirstName);
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
if(userOption == "1")
Console.WriteLine("Enter a new first Name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.FirstName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if (userOption == "2")
Console.WriteLine("Enter a new last name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.LastName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if(userOption == "3")
Console.WriteLine("Enter a new adress");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.Adress = newValue;
wtf.UpdateUserOnFile(adressBookList);
WriteToFile
class WriteAndReadToFile
private readonly string UserTextFile = ConfigurationManager.AppSettings["textFileName"];
public void WriteUserToFile(Person person)
using (StreamWriter sw = new StreamWriter(UserTextFile, true))
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
public void ReadFromFile(AdressBook ab)
string textLine;
try
using (StreamReader sr = new StreamReader(UserTextFile))
while ((textLine = sr.ReadLine()) != null)
string userInformation = textLine.Split(',');
Person p = new Person(userInformation[0], userInformation[1], userInformation[2]);
ab.AdressBookList.Add(p);
catch (FileNotFoundException fnf)
Console.WriteLine("File does not exist " + fnf);
catch (Exception e)
Console.WriteLine("Something went wrong" + e);
public void UpdateUserOnFile(List<Person> adressBookList)
// Remove old row
using (StreamWriter sw = new StreamWriter(UserTextFile))
sw.Flush();
foreach (var person in adressBookList)
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
c# beginner object-oriented
I have been taking some C# online courses the last couple of weeks in order to learn programming. Since I dont have any friends that are programming I found it hard to get feedback / reviews on the code I'm writing. Sure the code is running, but how about the code quality?
About the project
I have created a simple Address Book (console application) based on four classes:
- Main
- AdressBook
- Person
- WriteAndReadToFile
The application has the following abilities:
- Store friends
- Update friend information
- Remove user
- Show all users
- When adding/update/remove user it should be stored on a txt-file (which is loaded when the program start).
For simplicity I only added only name and adress in the application, there is also very bad data-input validation (focusing in learing OOP). Regarding the update function I am aware that it will update everything wich have a match on firstName.
Questions
- Am I using OOP in a correct way?
- I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Code
Main
class Program
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
ab.CreateUser();
break;
case "2":
ab.UpdateUserInformation();
break;
case "3":
ab.RemovePersonFromList();
break;
case "4":
ab.ShowAllPersonsInList();
break;
case "x":
ProgramIsRunning = false;
break;
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine("#1 Create new user");
Console.WriteLine("#2 Edit user information");
Console.WriteLine("#3 Delete existing user");
Console.WriteLine("#4 Show all users in adressBook");
private static AdressBook StartProgram()
AdressBook ab = new AdressBook();
//Start program by loading saved users from txt-file
WriteAndReadToFile writer = new WriteAndReadToFile();
writer.ReadFromFile(ab);
return ab;
Person
class Person
public string FirstName get; set;
public string LastName get; set;
public string Adress get; set;
public Person(string firstName, string lastName, string adress)
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
}
AdressBook
class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
wtf.WriteUserToFile(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person) => AdressBookList.Add(person);
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
//Show all Persons in AdressBookList
public void ShowAllPersonsInList()
foreach (var person in AdressBookList)
Console.WriteLine("FirstName: 0, LastName: 1, Adress: 2", person.FirstName, person.LastName, person.Adress);
public void UpdateUserInformation()
Console.WriteLine("Which information do you want to update?");
Console.WriteLine("#1: Firstname, #2: Lastname, 3# Adress");
var userOption = Console.ReadLine();
Console.WriteLine("Enter firstname on existing user to be updated");
var oldFirstName = Console.ReadLine();
UpdateUserFunction(userOption, oldFirstName);
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
if(userOption == "1")
Console.WriteLine("Enter a new first Name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.FirstName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if (userOption == "2")
Console.WriteLine("Enter a new last name");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.LastName = newValue;
wtf.UpdateUserOnFile(adressBookList);
else if(userOption == "3")
Console.WriteLine("Enter a new adress");
newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
person.Adress = newValue;
wtf.UpdateUserOnFile(adressBookList);
WriteToFile
class WriteAndReadToFile
private readonly string UserTextFile = ConfigurationManager.AppSettings["textFileName"];
public void WriteUserToFile(Person person)
using (StreamWriter sw = new StreamWriter(UserTextFile, true))
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
public void ReadFromFile(AdressBook ab)
string textLine;
try
using (StreamReader sr = new StreamReader(UserTextFile))
while ((textLine = sr.ReadLine()) != null)
string userInformation = textLine.Split(',');
Person p = new Person(userInformation[0], userInformation[1], userInformation[2]);
ab.AdressBookList.Add(p);
catch (FileNotFoundException fnf)
Console.WriteLine("File does not exist " + fnf);
catch (Exception e)
Console.WriteLine("Something went wrong" + e);
public void UpdateUserOnFile(List<Person> adressBookList)
// Remove old row
using (StreamWriter sw = new StreamWriter(UserTextFile))
sw.Flush();
foreach (var person in adressBookList)
sw.WriteLine(person.FirstName + "," + person.LastName + "," + person.Adress + ",");
c# beginner object-oriented
edited May 2 at 0:20
200_success
123k14142399
123k14142399
asked May 1 at 20:04
Philip
433
433
1
Welcome to Code Review! I hope you get some good answers. Your code already looks cleaner than a lot that I wrote when I started.
â Gerrit0
May 1 at 20:13
add a comment |Â
1
Welcome to Code Review! I hope you get some good answers. Your code already looks cleaner than a lot that I wrote when I started.
â Gerrit0
May 1 at 20:13
1
1
Welcome to Code Review! I hope you get some good answers. Your code already looks cleaner than a lot that I wrote when I started.
â Gerrit0
May 1 at 20:13
Welcome to Code Review! I hope you get some good answers. Your code already looks cleaner than a lot that I wrote when I started.
â Gerrit0
May 1 at 20:13
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
7
down vote
accepted
That's a great beginner's code!
One important thing to keep in mind when writing code is extendability. If tomorrow you wanted to add more user options, let's say remove all existing users, you would have to modify at least 2 methods, with your project growing, more such functions might arise, which leads to potentially forgetting to edit some of those methods and if you remember to modify them all, you still need to modify them all.
There are multiple techniques that you can use to avoid that problem, I will try to keep it simple.
Let's start with your program's Main
method. Currently you have a switch
there, which is usually indicator of bad code maintainability (most of the time), one way to solve it would be to introduce an interface and apply the Strategy Pattern, a simple and perhaps more suitable solution for your project, would be to avoid the interface and just use a class with a Dictionary
:
public class AdressBookAction
public int ID get;
public string Description get;
public Action<AdressBook> UserAction get;
public AdressBookAction(int id, string description, Action<AdressBook> userAction)
ID = id;
Description = description;
UserAction = userAction;
public override string ToString()
return $"Press ID to Description";
The ID
property is used to signify to the user how to access this command.
The UserAction
is a delegate, which means that it holds a reference to a method, more specifically it's Action<AdressBook>
meaning that any method with no return type and a single parameter of type AdressBook
will be suitable, this will allow us to use this single class in various cases and declare all of the necessary actions using only this class:
private static Dictionary<string, AdressBookAction> _userActions = new Dictionary<string, AdressBookAction>
["1"] = new AdressBookAction(1, "Create new user", book => book.CreateUser()),
["2"] = new AdressBookAction(2, "Edit user information", book => book.UpdateUserInformation()),
["3"] = new AdressBookAction(3, "Delete existing user", book => book.RemovePersonFromList()),
["4"] = new AdressBookAction(4, "Show all users in adressBook", book => book.ShowAllPersonsInList()),
;
You could write another class to wrap the Dictionary
there, which would remove the potential discrepancy between the Key
and the ID
of the AdressBookAction
, but I will leave it as it is.
With your Dictionary
declared your Main
method's while
loop will look like this:
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
if (userInput == "x")
ProgramIsRunning = false;
else if (_userActions.TryGetValue(userInput, out var action))
action.UserAction.Invoke(ab);
Also PrintUserOptions
, currently requires manual change, because your options are not stored in any collection, with the Dictionary
, we can simply do:
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine(string.Join(Environment.NewLine, _userActions.Values));
This will utilize the overridden ToString()
method in the AdressBookAction
class.
Moving on to your AdressBook
class.
You can apply similar technique to your UpdateUserFunction
, I will leave that up to you.
You shouldn't not use the backing field of a property outside of the property's body.
wtf.UpdateUserOnFile(adressBookList);
Methods are very useful, they allow you to avoid repetitive code and they reduce the need for comments, multiple related instructions unified under 1 descriptive name. The reason I'm bringing this up is this part:
AddPersonToList(person);
wtf.WriteUserToFile(person);
I can think of few cases where you would want those separated, but in your project it seems that they would be better off in a single method.
Oh I forgot to mention that they usually serve 1 purpose, take a look at those 2 functions:
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person)
AdressBookList.Add(person);
wtf.WriteUserToFile(person);
Now take a look at this one:
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
Did you spot the difference? (besides the fact that they serve 2 different roles).
add a comment |Â
up vote
3
down vote
Spelling
This isn't that big of a deal but it was the first thing I noticed, Address has two d's. The reason this doesn't matter that much is that you're consistent; however, it might confuse someone having it spelt wrong so take that into consideration. There are very handy tools in visual studio for renaming variables.
Repetition
Your UpdateUserFunction
is very repetitive. Personally, I would have wrote it like this to avoid large repeated chucks of code; however, sometimes simple is better than not repeating yourself.
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
switch (userOption)
case "1":
UpdateUser("first name", person => person.FirstName = newValue);
break;
case "2":
UpdateUser("last name", person => person.LastName = newValue);
break;
case "3":
UpdateUser("adress", person => person.Adress = newValue);
break;
default:
Console.WriteLine("Unknown user option!");
break;
private void UpdateUser(string label, Action<Person, string> updateAction)
Console.WriteLine($"Enter a new label");
var newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
updateAction(person, newValue);
wtf.UpdateUserOnFile(adressBookList);
Inconsistency
I noticed that in the first part of your program you use a switch
statement for handling userOption
but then in the UpdateUserFunction
you used an if-statement. The switch statement is a nice use in this case since you're comparing the same variable and you could end up adding more userOption
values later.
var
You can use the keyword var
instead of typing the variables type twice (e.g. StreamWriter sw = new StreamWriter(UserTextFile)
can become var sw = new StreamWriter(UserTextFile)
. This is mostly preference, but you can imagine how convenient this will be. It has no effect on performance, the compiler is just deducing the type at compile-time.
Conclusion
That's all the nit-picking I could manage, haha. Overall, your code looks pretty good, especially for a beginner!
add a comment |Â
up vote
3
down vote
Separation
First thing which I notice is that your code is very tightly coupled with the console. I can imagine that you, in version 2.0, want to create a UI for your users.
An improvement could be to separate the code which involves getting the input for the firstname, lastname and address and the code that involves validating and storing the input.
So let the Console part be in charge of getting the required input and make your own code accept and process that input.
Example:
Responsibilities
Next thing is try to assign the appropriate responsibilities to the different objects that you have. Currently the AddressBook class has a method for creating a User (Or Person). Try to think about the real life situation, an it's not the responsibility of the address book to create a new person, it only has the option to add a new person entry.
The address book has too much responsibilities now.
Example:
class Program
{
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
var person = new Person(firstName, lastName, adress);
ab.AddEntry(person);
break;
public class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
public void AddEntry(Person person)
AddPersonToList(person);
wtf.WriteUserToFile(person);
In my example you'll see that I've moved the Console.Readlines to the Main method, when you now want to move away from using the console as input, you are able to do so. Just replace the Console.Readlines with input you got from a javascript frontend or WPF UI.
You'll also see that I moved the creating of the person to the main method, the address book was doing two things, creating a person and adding it to the addressbooklist.
Try to follow the Single Responsibility principle this will help maintaining and re-usability of the code (https://stackoverflow.com/questions/10620022/what-is-an-example-of-the-single-responsibility-principle)
Question answers:
I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Apply the single responsibility principle here. In your code right now every method is also responsible for writing the create/update/delete actions to the file.
You could choose to only "update" the file once by writing the latest state of the address book to file.
My suggestion would be to have a method which writes you entire address book to a file and you would call this when the application is stopped (in your case when 'x' is pressed)
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
That's a great beginner's code!
One important thing to keep in mind when writing code is extendability. If tomorrow you wanted to add more user options, let's say remove all existing users, you would have to modify at least 2 methods, with your project growing, more such functions might arise, which leads to potentially forgetting to edit some of those methods and if you remember to modify them all, you still need to modify them all.
There are multiple techniques that you can use to avoid that problem, I will try to keep it simple.
Let's start with your program's Main
method. Currently you have a switch
there, which is usually indicator of bad code maintainability (most of the time), one way to solve it would be to introduce an interface and apply the Strategy Pattern, a simple and perhaps more suitable solution for your project, would be to avoid the interface and just use a class with a Dictionary
:
public class AdressBookAction
public int ID get;
public string Description get;
public Action<AdressBook> UserAction get;
public AdressBookAction(int id, string description, Action<AdressBook> userAction)
ID = id;
Description = description;
UserAction = userAction;
public override string ToString()
return $"Press ID to Description";
The ID
property is used to signify to the user how to access this command.
The UserAction
is a delegate, which means that it holds a reference to a method, more specifically it's Action<AdressBook>
meaning that any method with no return type and a single parameter of type AdressBook
will be suitable, this will allow us to use this single class in various cases and declare all of the necessary actions using only this class:
private static Dictionary<string, AdressBookAction> _userActions = new Dictionary<string, AdressBookAction>
["1"] = new AdressBookAction(1, "Create new user", book => book.CreateUser()),
["2"] = new AdressBookAction(2, "Edit user information", book => book.UpdateUserInformation()),
["3"] = new AdressBookAction(3, "Delete existing user", book => book.RemovePersonFromList()),
["4"] = new AdressBookAction(4, "Show all users in adressBook", book => book.ShowAllPersonsInList()),
;
You could write another class to wrap the Dictionary
there, which would remove the potential discrepancy between the Key
and the ID
of the AdressBookAction
, but I will leave it as it is.
With your Dictionary
declared your Main
method's while
loop will look like this:
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
if (userInput == "x")
ProgramIsRunning = false;
else if (_userActions.TryGetValue(userInput, out var action))
action.UserAction.Invoke(ab);
Also PrintUserOptions
, currently requires manual change, because your options are not stored in any collection, with the Dictionary
, we can simply do:
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine(string.Join(Environment.NewLine, _userActions.Values));
This will utilize the overridden ToString()
method in the AdressBookAction
class.
Moving on to your AdressBook
class.
You can apply similar technique to your UpdateUserFunction
, I will leave that up to you.
You shouldn't not use the backing field of a property outside of the property's body.
wtf.UpdateUserOnFile(adressBookList);
Methods are very useful, they allow you to avoid repetitive code and they reduce the need for comments, multiple related instructions unified under 1 descriptive name. The reason I'm bringing this up is this part:
AddPersonToList(person);
wtf.WriteUserToFile(person);
I can think of few cases where you would want those separated, but in your project it seems that they would be better off in a single method.
Oh I forgot to mention that they usually serve 1 purpose, take a look at those 2 functions:
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person)
AdressBookList.Add(person);
wtf.WriteUserToFile(person);
Now take a look at this one:
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
Did you spot the difference? (besides the fact that they serve 2 different roles).
add a comment |Â
up vote
7
down vote
accepted
That's a great beginner's code!
One important thing to keep in mind when writing code is extendability. If tomorrow you wanted to add more user options, let's say remove all existing users, you would have to modify at least 2 methods, with your project growing, more such functions might arise, which leads to potentially forgetting to edit some of those methods and if you remember to modify them all, you still need to modify them all.
There are multiple techniques that you can use to avoid that problem, I will try to keep it simple.
Let's start with your program's Main
method. Currently you have a switch
there, which is usually indicator of bad code maintainability (most of the time), one way to solve it would be to introduce an interface and apply the Strategy Pattern, a simple and perhaps more suitable solution for your project, would be to avoid the interface and just use a class with a Dictionary
:
public class AdressBookAction
public int ID get;
public string Description get;
public Action<AdressBook> UserAction get;
public AdressBookAction(int id, string description, Action<AdressBook> userAction)
ID = id;
Description = description;
UserAction = userAction;
public override string ToString()
return $"Press ID to Description";
The ID
property is used to signify to the user how to access this command.
The UserAction
is a delegate, which means that it holds a reference to a method, more specifically it's Action<AdressBook>
meaning that any method with no return type and a single parameter of type AdressBook
will be suitable, this will allow us to use this single class in various cases and declare all of the necessary actions using only this class:
private static Dictionary<string, AdressBookAction> _userActions = new Dictionary<string, AdressBookAction>
["1"] = new AdressBookAction(1, "Create new user", book => book.CreateUser()),
["2"] = new AdressBookAction(2, "Edit user information", book => book.UpdateUserInformation()),
["3"] = new AdressBookAction(3, "Delete existing user", book => book.RemovePersonFromList()),
["4"] = new AdressBookAction(4, "Show all users in adressBook", book => book.ShowAllPersonsInList()),
;
You could write another class to wrap the Dictionary
there, which would remove the potential discrepancy between the Key
and the ID
of the AdressBookAction
, but I will leave it as it is.
With your Dictionary
declared your Main
method's while
loop will look like this:
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
if (userInput == "x")
ProgramIsRunning = false;
else if (_userActions.TryGetValue(userInput, out var action))
action.UserAction.Invoke(ab);
Also PrintUserOptions
, currently requires manual change, because your options are not stored in any collection, with the Dictionary
, we can simply do:
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine(string.Join(Environment.NewLine, _userActions.Values));
This will utilize the overridden ToString()
method in the AdressBookAction
class.
Moving on to your AdressBook
class.
You can apply similar technique to your UpdateUserFunction
, I will leave that up to you.
You shouldn't not use the backing field of a property outside of the property's body.
wtf.UpdateUserOnFile(adressBookList);
Methods are very useful, they allow you to avoid repetitive code and they reduce the need for comments, multiple related instructions unified under 1 descriptive name. The reason I'm bringing this up is this part:
AddPersonToList(person);
wtf.WriteUserToFile(person);
I can think of few cases where you would want those separated, but in your project it seems that they would be better off in a single method.
Oh I forgot to mention that they usually serve 1 purpose, take a look at those 2 functions:
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person)
AdressBookList.Add(person);
wtf.WriteUserToFile(person);
Now take a look at this one:
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
Did you spot the difference? (besides the fact that they serve 2 different roles).
add a comment |Â
up vote
7
down vote
accepted
up vote
7
down vote
accepted
That's a great beginner's code!
One important thing to keep in mind when writing code is extendability. If tomorrow you wanted to add more user options, let's say remove all existing users, you would have to modify at least 2 methods, with your project growing, more such functions might arise, which leads to potentially forgetting to edit some of those methods and if you remember to modify them all, you still need to modify them all.
There are multiple techniques that you can use to avoid that problem, I will try to keep it simple.
Let's start with your program's Main
method. Currently you have a switch
there, which is usually indicator of bad code maintainability (most of the time), one way to solve it would be to introduce an interface and apply the Strategy Pattern, a simple and perhaps more suitable solution for your project, would be to avoid the interface and just use a class with a Dictionary
:
public class AdressBookAction
public int ID get;
public string Description get;
public Action<AdressBook> UserAction get;
public AdressBookAction(int id, string description, Action<AdressBook> userAction)
ID = id;
Description = description;
UserAction = userAction;
public override string ToString()
return $"Press ID to Description";
The ID
property is used to signify to the user how to access this command.
The UserAction
is a delegate, which means that it holds a reference to a method, more specifically it's Action<AdressBook>
meaning that any method with no return type and a single parameter of type AdressBook
will be suitable, this will allow us to use this single class in various cases and declare all of the necessary actions using only this class:
private static Dictionary<string, AdressBookAction> _userActions = new Dictionary<string, AdressBookAction>
["1"] = new AdressBookAction(1, "Create new user", book => book.CreateUser()),
["2"] = new AdressBookAction(2, "Edit user information", book => book.UpdateUserInformation()),
["3"] = new AdressBookAction(3, "Delete existing user", book => book.RemovePersonFromList()),
["4"] = new AdressBookAction(4, "Show all users in adressBook", book => book.ShowAllPersonsInList()),
;
You could write another class to wrap the Dictionary
there, which would remove the potential discrepancy between the Key
and the ID
of the AdressBookAction
, but I will leave it as it is.
With your Dictionary
declared your Main
method's while
loop will look like this:
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
if (userInput == "x")
ProgramIsRunning = false;
else if (_userActions.TryGetValue(userInput, out var action))
action.UserAction.Invoke(ab);
Also PrintUserOptions
, currently requires manual change, because your options are not stored in any collection, with the Dictionary
, we can simply do:
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine(string.Join(Environment.NewLine, _userActions.Values));
This will utilize the overridden ToString()
method in the AdressBookAction
class.
Moving on to your AdressBook
class.
You can apply similar technique to your UpdateUserFunction
, I will leave that up to you.
You shouldn't not use the backing field of a property outside of the property's body.
wtf.UpdateUserOnFile(adressBookList);
Methods are very useful, they allow you to avoid repetitive code and they reduce the need for comments, multiple related instructions unified under 1 descriptive name. The reason I'm bringing this up is this part:
AddPersonToList(person);
wtf.WriteUserToFile(person);
I can think of few cases where you would want those separated, but in your project it seems that they would be better off in a single method.
Oh I forgot to mention that they usually serve 1 purpose, take a look at those 2 functions:
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person)
AdressBookList.Add(person);
wtf.WriteUserToFile(person);
Now take a look at this one:
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
Did you spot the difference? (besides the fact that they serve 2 different roles).
That's a great beginner's code!
One important thing to keep in mind when writing code is extendability. If tomorrow you wanted to add more user options, let's say remove all existing users, you would have to modify at least 2 methods, with your project growing, more such functions might arise, which leads to potentially forgetting to edit some of those methods and if you remember to modify them all, you still need to modify them all.
There are multiple techniques that you can use to avoid that problem, I will try to keep it simple.
Let's start with your program's Main
method. Currently you have a switch
there, which is usually indicator of bad code maintainability (most of the time), one way to solve it would be to introduce an interface and apply the Strategy Pattern, a simple and perhaps more suitable solution for your project, would be to avoid the interface and just use a class with a Dictionary
:
public class AdressBookAction
public int ID get;
public string Description get;
public Action<AdressBook> UserAction get;
public AdressBookAction(int id, string description, Action<AdressBook> userAction)
ID = id;
Description = description;
UserAction = userAction;
public override string ToString()
return $"Press ID to Description";
The ID
property is used to signify to the user how to access this command.
The UserAction
is a delegate, which means that it holds a reference to a method, more specifically it's Action<AdressBook>
meaning that any method with no return type and a single parameter of type AdressBook
will be suitable, this will allow us to use this single class in various cases and declare all of the necessary actions using only this class:
private static Dictionary<string, AdressBookAction> _userActions = new Dictionary<string, AdressBookAction>
["1"] = new AdressBookAction(1, "Create new user", book => book.CreateUser()),
["2"] = new AdressBookAction(2, "Edit user information", book => book.UpdateUserInformation()),
["3"] = new AdressBookAction(3, "Delete existing user", book => book.RemovePersonFromList()),
["4"] = new AdressBookAction(4, "Show all users in adressBook", book => book.ShowAllPersonsInList()),
;
You could write another class to wrap the Dictionary
there, which would remove the potential discrepancy between the Key
and the ID
of the AdressBookAction
, but I will leave it as it is.
With your Dictionary
declared your Main
method's while
loop will look like this:
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
if (userInput == "x")
ProgramIsRunning = false;
else if (_userActions.TryGetValue(userInput, out var action))
action.UserAction.Invoke(ab);
Also PrintUserOptions
, currently requires manual change, because your options are not stored in any collection, with the Dictionary
, we can simply do:
private static void PrintUserOptions()
Console.WriteLine("Choose one of the following options: ");
Console.WriteLine(string.Join(Environment.NewLine, _userActions.Values));
This will utilize the overridden ToString()
method in the AdressBookAction
class.
Moving on to your AdressBook
class.
You can apply similar technique to your UpdateUserFunction
, I will leave that up to you.
You shouldn't not use the backing field of a property outside of the property's body.
wtf.UpdateUserOnFile(adressBookList);
Methods are very useful, they allow you to avoid repetitive code and they reduce the need for comments, multiple related instructions unified under 1 descriptive name. The reason I'm bringing this up is this part:
AddPersonToList(person);
wtf.WriteUserToFile(person);
I can think of few cases where you would want those separated, but in your project it seems that they would be better off in a single method.
Oh I forgot to mention that they usually serve 1 purpose, take a look at those 2 functions:
// Create instance of Person-class and call AddPersonToList-method
public void CreateUser()
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
Person person = new Person(firstName, lastName, adress);
AddPersonToList(person);
// Add new person to AdressBookList
private void AddPersonToList(Person person)
AdressBookList.Add(person);
wtf.WriteUserToFile(person);
Now take a look at this one:
//Remove user from list where first and last name match
public void RemovePersonFromList()
Console.WriteLine("Enter firstName of the user you want to remove");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastname of the user you want to remove");
var lastName = Console.ReadLine();
AdressBookList.RemoveAll(item => item.FirstName == firstName && item.LastName == lastName);
wtf.UpdateUserOnFile(adressBookList);
Did you spot the difference? (besides the fact that they serve 2 different roles).
answered May 1 at 22:01
Denis
6,15921453
6,15921453
add a comment |Â
add a comment |Â
up vote
3
down vote
Spelling
This isn't that big of a deal but it was the first thing I noticed, Address has two d's. The reason this doesn't matter that much is that you're consistent; however, it might confuse someone having it spelt wrong so take that into consideration. There are very handy tools in visual studio for renaming variables.
Repetition
Your UpdateUserFunction
is very repetitive. Personally, I would have wrote it like this to avoid large repeated chucks of code; however, sometimes simple is better than not repeating yourself.
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
switch (userOption)
case "1":
UpdateUser("first name", person => person.FirstName = newValue);
break;
case "2":
UpdateUser("last name", person => person.LastName = newValue);
break;
case "3":
UpdateUser("adress", person => person.Adress = newValue);
break;
default:
Console.WriteLine("Unknown user option!");
break;
private void UpdateUser(string label, Action<Person, string> updateAction)
Console.WriteLine($"Enter a new label");
var newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
updateAction(person, newValue);
wtf.UpdateUserOnFile(adressBookList);
Inconsistency
I noticed that in the first part of your program you use a switch
statement for handling userOption
but then in the UpdateUserFunction
you used an if-statement. The switch statement is a nice use in this case since you're comparing the same variable and you could end up adding more userOption
values later.
var
You can use the keyword var
instead of typing the variables type twice (e.g. StreamWriter sw = new StreamWriter(UserTextFile)
can become var sw = new StreamWriter(UserTextFile)
. This is mostly preference, but you can imagine how convenient this will be. It has no effect on performance, the compiler is just deducing the type at compile-time.
Conclusion
That's all the nit-picking I could manage, haha. Overall, your code looks pretty good, especially for a beginner!
add a comment |Â
up vote
3
down vote
Spelling
This isn't that big of a deal but it was the first thing I noticed, Address has two d's. The reason this doesn't matter that much is that you're consistent; however, it might confuse someone having it spelt wrong so take that into consideration. There are very handy tools in visual studio for renaming variables.
Repetition
Your UpdateUserFunction
is very repetitive. Personally, I would have wrote it like this to avoid large repeated chucks of code; however, sometimes simple is better than not repeating yourself.
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
switch (userOption)
case "1":
UpdateUser("first name", person => person.FirstName = newValue);
break;
case "2":
UpdateUser("last name", person => person.LastName = newValue);
break;
case "3":
UpdateUser("adress", person => person.Adress = newValue);
break;
default:
Console.WriteLine("Unknown user option!");
break;
private void UpdateUser(string label, Action<Person, string> updateAction)
Console.WriteLine($"Enter a new label");
var newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
updateAction(person, newValue);
wtf.UpdateUserOnFile(adressBookList);
Inconsistency
I noticed that in the first part of your program you use a switch
statement for handling userOption
but then in the UpdateUserFunction
you used an if-statement. The switch statement is a nice use in this case since you're comparing the same variable and you could end up adding more userOption
values later.
var
You can use the keyword var
instead of typing the variables type twice (e.g. StreamWriter sw = new StreamWriter(UserTextFile)
can become var sw = new StreamWriter(UserTextFile)
. This is mostly preference, but you can imagine how convenient this will be. It has no effect on performance, the compiler is just deducing the type at compile-time.
Conclusion
That's all the nit-picking I could manage, haha. Overall, your code looks pretty good, especially for a beginner!
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Spelling
This isn't that big of a deal but it was the first thing I noticed, Address has two d's. The reason this doesn't matter that much is that you're consistent; however, it might confuse someone having it spelt wrong so take that into consideration. There are very handy tools in visual studio for renaming variables.
Repetition
Your UpdateUserFunction
is very repetitive. Personally, I would have wrote it like this to avoid large repeated chucks of code; however, sometimes simple is better than not repeating yourself.
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
switch (userOption)
case "1":
UpdateUser("first name", person => person.FirstName = newValue);
break;
case "2":
UpdateUser("last name", person => person.LastName = newValue);
break;
case "3":
UpdateUser("adress", person => person.Adress = newValue);
break;
default:
Console.WriteLine("Unknown user option!");
break;
private void UpdateUser(string label, Action<Person, string> updateAction)
Console.WriteLine($"Enter a new label");
var newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
updateAction(person, newValue);
wtf.UpdateUserOnFile(adressBookList);
Inconsistency
I noticed that in the first part of your program you use a switch
statement for handling userOption
but then in the UpdateUserFunction
you used an if-statement. The switch statement is a nice use in this case since you're comparing the same variable and you could end up adding more userOption
values later.
var
You can use the keyword var
instead of typing the variables type twice (e.g. StreamWriter sw = new StreamWriter(UserTextFile)
can become var sw = new StreamWriter(UserTextFile)
. This is mostly preference, but you can imagine how convenient this will be. It has no effect on performance, the compiler is just deducing the type at compile-time.
Conclusion
That's all the nit-picking I could manage, haha. Overall, your code looks pretty good, especially for a beginner!
Spelling
This isn't that big of a deal but it was the first thing I noticed, Address has two d's. The reason this doesn't matter that much is that you're consistent; however, it might confuse someone having it spelt wrong so take that into consideration. There are very handy tools in visual studio for renaming variables.
Repetition
Your UpdateUserFunction
is very repetitive. Personally, I would have wrote it like this to avoid large repeated chucks of code; however, sometimes simple is better than not repeating yourself.
private void UpdateUserFunction(string userOption, string oldFirstName)
var personsWithMatchingFirstName = AdressBookList.Where(person => person.FirstName == oldFirstName);
string newValue;
switch (userOption)
case "1":
UpdateUser("first name", person => person.FirstName = newValue);
break;
case "2":
UpdateUser("last name", person => person.LastName = newValue);
break;
case "3":
UpdateUser("adress", person => person.Adress = newValue);
break;
default:
Console.WriteLine("Unknown user option!");
break;
private void UpdateUser(string label, Action<Person, string> updateAction)
Console.WriteLine($"Enter a new label");
var newValue = Console.ReadLine();
foreach (var person in personsWithMatchingFirstName)
updateAction(person, newValue);
wtf.UpdateUserOnFile(adressBookList);
Inconsistency
I noticed that in the first part of your program you use a switch
statement for handling userOption
but then in the UpdateUserFunction
you used an if-statement. The switch statement is a nice use in this case since you're comparing the same variable and you could end up adding more userOption
values later.
var
You can use the keyword var
instead of typing the variables type twice (e.g. StreamWriter sw = new StreamWriter(UserTextFile)
can become var sw = new StreamWriter(UserTextFile)
. This is mostly preference, but you can imagine how convenient this will be. It has no effect on performance, the compiler is just deducing the type at compile-time.
Conclusion
That's all the nit-picking I could manage, haha. Overall, your code looks pretty good, especially for a beginner!
answered May 1 at 20:59
Shelby115
1,354516
1,354516
add a comment |Â
add a comment |Â
up vote
3
down vote
Separation
First thing which I notice is that your code is very tightly coupled with the console. I can imagine that you, in version 2.0, want to create a UI for your users.
An improvement could be to separate the code which involves getting the input for the firstname, lastname and address and the code that involves validating and storing the input.
So let the Console part be in charge of getting the required input and make your own code accept and process that input.
Example:
Responsibilities
Next thing is try to assign the appropriate responsibilities to the different objects that you have. Currently the AddressBook class has a method for creating a User (Or Person). Try to think about the real life situation, an it's not the responsibility of the address book to create a new person, it only has the option to add a new person entry.
The address book has too much responsibilities now.
Example:
class Program
{
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
var person = new Person(firstName, lastName, adress);
ab.AddEntry(person);
break;
public class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
public void AddEntry(Person person)
AddPersonToList(person);
wtf.WriteUserToFile(person);
In my example you'll see that I've moved the Console.Readlines to the Main method, when you now want to move away from using the console as input, you are able to do so. Just replace the Console.Readlines with input you got from a javascript frontend or WPF UI.
You'll also see that I moved the creating of the person to the main method, the address book was doing two things, creating a person and adding it to the addressbooklist.
Try to follow the Single Responsibility principle this will help maintaining and re-usability of the code (https://stackoverflow.com/questions/10620022/what-is-an-example-of-the-single-responsibility-principle)
Question answers:
I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Apply the single responsibility principle here. In your code right now every method is also responsible for writing the create/update/delete actions to the file.
You could choose to only "update" the file once by writing the latest state of the address book to file.
My suggestion would be to have a method which writes you entire address book to a file and you would call this when the application is stopped (in your case when 'x' is pressed)
add a comment |Â
up vote
3
down vote
Separation
First thing which I notice is that your code is very tightly coupled with the console. I can imagine that you, in version 2.0, want to create a UI for your users.
An improvement could be to separate the code which involves getting the input for the firstname, lastname and address and the code that involves validating and storing the input.
So let the Console part be in charge of getting the required input and make your own code accept and process that input.
Example:
Responsibilities
Next thing is try to assign the appropriate responsibilities to the different objects that you have. Currently the AddressBook class has a method for creating a User (Or Person). Try to think about the real life situation, an it's not the responsibility of the address book to create a new person, it only has the option to add a new person entry.
The address book has too much responsibilities now.
Example:
class Program
{
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
var person = new Person(firstName, lastName, adress);
ab.AddEntry(person);
break;
public class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
public void AddEntry(Person person)
AddPersonToList(person);
wtf.WriteUserToFile(person);
In my example you'll see that I've moved the Console.Readlines to the Main method, when you now want to move away from using the console as input, you are able to do so. Just replace the Console.Readlines with input you got from a javascript frontend or WPF UI.
You'll also see that I moved the creating of the person to the main method, the address book was doing two things, creating a person and adding it to the addressbooklist.
Try to follow the Single Responsibility principle this will help maintaining and re-usability of the code (https://stackoverflow.com/questions/10620022/what-is-an-example-of-the-single-responsibility-principle)
Question answers:
I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Apply the single responsibility principle here. In your code right now every method is also responsible for writing the create/update/delete actions to the file.
You could choose to only "update" the file once by writing the latest state of the address book to file.
My suggestion would be to have a method which writes you entire address book to a file and you would call this when the application is stopped (in your case when 'x' is pressed)
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Separation
First thing which I notice is that your code is very tightly coupled with the console. I can imagine that you, in version 2.0, want to create a UI for your users.
An improvement could be to separate the code which involves getting the input for the firstname, lastname and address and the code that involves validating and storing the input.
So let the Console part be in charge of getting the required input and make your own code accept and process that input.
Example:
Responsibilities
Next thing is try to assign the appropriate responsibilities to the different objects that you have. Currently the AddressBook class has a method for creating a User (Or Person). Try to think about the real life situation, an it's not the responsibility of the address book to create a new person, it only has the option to add a new person entry.
The address book has too much responsibilities now.
Example:
class Program
{
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
var person = new Person(firstName, lastName, adress);
ab.AddEntry(person);
break;
public class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
public void AddEntry(Person person)
AddPersonToList(person);
wtf.WriteUserToFile(person);
In my example you'll see that I've moved the Console.Readlines to the Main method, when you now want to move away from using the console as input, you are able to do so. Just replace the Console.Readlines with input you got from a javascript frontend or WPF UI.
You'll also see that I moved the creating of the person to the main method, the address book was doing two things, creating a person and adding it to the addressbooklist.
Try to follow the Single Responsibility principle this will help maintaining and re-usability of the code (https://stackoverflow.com/questions/10620022/what-is-an-example-of-the-single-responsibility-principle)
Question answers:
I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Apply the single responsibility principle here. In your code right now every method is also responsible for writing the create/update/delete actions to the file.
You could choose to only "update" the file once by writing the latest state of the address book to file.
My suggestion would be to have a method which writes you entire address book to a file and you would call this when the application is stopped (in your case when 'x' is pressed)
Separation
First thing which I notice is that your code is very tightly coupled with the console. I can imagine that you, in version 2.0, want to create a UI for your users.
An improvement could be to separate the code which involves getting the input for the firstname, lastname and address and the code that involves validating and storing the input.
So let the Console part be in charge of getting the required input and make your own code accept and process that input.
Example:
Responsibilities
Next thing is try to assign the appropriate responsibilities to the different objects that you have. Currently the AddressBook class has a method for creating a User (Or Person). Try to think about the real life situation, an it's not the responsibility of the address book to create a new person, it only has the option to add a new person entry.
The address book has too much responsibilities now.
Example:
class Program
{
static void Main(string args)
bool ProgramIsRunning = true;
AdressBook ab = StartProgram();
Console.WriteLine("--------- AdressBook 1.0 ---------");
while (ProgramIsRunning)
// Print user options
PrintUserOptions();
var userInput = Console.ReadLine();
switch (userInput)
case "1":
Console.WriteLine("Enter firstName:");
var firstName = Console.ReadLine();
Console.WriteLine("Enter lastName:");
var lastName = Console.ReadLine();
Console.WriteLine("Enter adress:");
var adress = Console.ReadLine();
var person = new Person(firstName, lastName, adress);
ab.AddEntry(person);
break;
public class AdressBook
private WriteAndReadToFile wtf;
private List<Person> adressBookList = new List<Person>();
public List<Person> AdressBookList
get return adressBookList;
set this.adressBookList = value;
public AdressBook()
AdressBookList = new List<Person>();
wtf = new WriteAndReadToFile();
public void AddEntry(Person person)
AddPersonToList(person);
wtf.WriteUserToFile(person);
In my example you'll see that I've moved the Console.Readlines to the Main method, when you now want to move away from using the console as input, you are able to do so. Just replace the Console.Readlines with input you got from a javascript frontend or WPF UI.
You'll also see that I moved the creating of the person to the main method, the address book was doing two things, creating a person and adding it to the addressbooklist.
Try to follow the Single Responsibility principle this will help maintaining and re-usability of the code (https://stackoverflow.com/questions/10620022/what-is-an-example-of-the-single-responsibility-principle)
Question answers:
I found it hard to keep the text-file in a correct "state" after updates & deletes and begun to flush the file after and rewrite the file instead. Is that bad practice?
Apply the single responsibility principle here. In your code right now every method is also responsible for writing the create/update/delete actions to the file.
You could choose to only "update" the file once by writing the latest state of the address book to file.
My suggestion would be to have a method which writes you entire address book to a file and you would call this when the application is stopped (in your case when 'x' is pressed)
edited May 3 at 7:49
answered May 2 at 15:23
Chris Ketelaar
1115
1115
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193387%2faddress-book-console-application%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Welcome to Code Review! I hope you get some good answers. Your code already looks cleaner than a lot that I wrote when I started.
â Gerrit0
May 1 at 20:13