This question already has answers here:
How do I calculate someone's age based on a DateTime type birthday?
(74 answers)
Closed 7 months ago.
I have a class as below:
class Member
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
private int _age;
public int Age
{
get { return _age; }
private set { _age = DateTime.Now.Year - Birthday.Year; }
}
}
In the Main method, I assign member values and I want to get each member's age, but every result is zero, Why? How to solve this problem? Thanks!
class Program
{
static void Main(string[] args)
{
List<Member> memberList = new List<Member>(); //using System.Collections.Generic;
memberList.Add(new Member() { Name = "Andy", Birthday = new DateTime(1971, 7, 26)});
memberList.Add(new Member() { Name = "Mike", Birthday = new DateTime(1982, 1, 17)});
memberList.Add(new Member() { Name = "Lucy", Birthday = new DateTime(1993, 9, 28)});
foreach (var m in memberList)
{
Console.WriteLine(m.Age); //m.Age = 0
}
}
}```
You need to update your class like this because the setter are not doing the operation since youre returning the variable on the get and thats why you got a 0 :
public class Member
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
public int Age
{
get { return DateTime.Now.Year - Birthday.Year; }
}
}
after that change you can get the agre,btw you can calculate the age easier with a timespan to be more exact.
Please return the age from getter method like this.
class Member
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
private int _age;
public int Age
{
get { return DateTime.Now.Year - Birthday.Year; }
private set { _age = DateTime.Now.Year - Birthday.Year; }
}
}
You can remove the calculation from setter method.
Please see the output-
Related
This question already has answers here:
how to check if List<T> element contains an item with a Particular Property Value
(7 answers)
Find object in list with given property value then find dictionary value
(1 answer)
How to get/find an object by property value in a list
(4 answers)
Using Contains() to check multiple object values exist in list before adding new list?
(2 answers)
Closed 2 years ago.
so I'm trying to check to see whether or not the inputted employee name is equal to an employee name in a list. Can't for the life of me figure out how to achieve this.
Program.cs
private static void ReportPersonalUsage()
{
string employeename = ReadString("Employee Name:");
Manager_UI.ReportPersonalUsage(employeename);
}
Manager_UI.cs
public static void ReportPersonalUsage(string employeename)
{
List<Transaction> Transactions = StockManager.GetAllTransactions();
Console.WriteLine("\nPersonal Usage Log:");
Console.WriteLine("\t{0, -19} {1, -6} {2, -3} {3, -10} {4, -10}",
"Date Taken",
"Type",
"ID",
"Name",
"Employee");
foreach (Transaction transaction in Transactions)
{
if (transaction.GetEmployee() == employeename)
{
DisplayTransaction(transaction);
}
}
}
Transaction.cs
class Transaction
{
//Transaction Get/Set
private Item Item { get; }
private string Employee { get; }
private string Type { get; }
private DateTime Date { get; }
private double Price { get; }
//Transaction
public Transaction(Item item, string type, string employee, DateTime date, double itemprice)
{
this.Item = item;
this.Type = type;
this.Employee = employee;
this.Date = date;
this.Price = itemprice;
}
//Get item
public Item GetItem()
{
return this.Item;
}
//Get employee
public string GetEmployee()
{
return this.Employee;
}
//Get transaction type
public new string GetType()
{
return this.Type;
}
//Get transaction price
public double GetPrice()
{
return this.Price;
}
//Get transaction date
public DateTime GetDate()
{
return this.Date;
}
}
Not to sure about how to do it though, still fresh to all of this, thanks to anyone that can lend a hand.
public static void ReportPersonalUsage(string employeename)
{
List<Transaction> Transactions = StockManager.GetAllTransactions();
bool isEmployeeExist = Transactions.Any(t => t.GetEmployee() == employeename);
if (isEmployeeExist == false)
{
Console.WriteLine(employeename + " Has Not Taken An Item From Stock Yet, Please Try Again");
}
else if (isEmployeeExist == true)
{
Console.WriteLine("\nPersonal Usage Log:");
Console.WriteLine("\t{0, -19} {1, -6} {2, -3} {3, -10} {4, -10}",
"Date Taken",
"Type",
"ID",
"Name",
"Employee");
foreach (Transaction transaction in Transactions)
{
DisplayTransaction(transaction);
}
}
}
public class Transaction
{
//Transaction Get/Set
public Item Item { get; private set; }
public string Employee { get; private set; }
public string Type { get; private set; }
public DateTime Date { get; private set; }
public double Price { get; private set; }
//Transaction
public Transaction(Item item, string type, string employee, DateTime date, double itemprice)
{
Item = item;
Type = type;
Employee = employee;
Date = date;
Price = itemprice;
}
}
public static void ReportPersonalUsage(string employeeName)
{
IEnumerable<Transaction> transactions = StockManager.GetAllTransactions();
DisplayHeader();
foreach(Transaction transaction in transactions)
{
if (transaction.Employee == employeeName)
{
DisplayTransaction(transaction);
}
}
}
private static void DisplayHeader()
{
Console.WriteLine("\nPersonal Usage Log:");
Console.WriteLine("\t{0, -19} {1, -6} {2, -3} {3, -10} {4, -10}",
"Date Taken",
"Type",
"ID",
"Name",
"Employee");
}
private static void DisplayTransaction(Transaction transaction)
{
//add the display logic
}
You should work with IEnumerable to take advantage of lazy loading.
Only iterate the collection at the point where you need the data.
Use properties instead of methods in the Transaction POCO.
Make the private properties to public and make the set private like public double Price { get; private set;}
I've created a class called "Person" and I'm trying to write a method called Birthday that would increase the attribute "Age" by one. I know it's dumb to try and define a variable using Age, but I can't figure out how to pass a variable from Main into Person.Birthday. I also probably don't need that while loop, but I was just trying a bunch of things. Anyway, help would be appreciated.
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "Frank";
p1.Age = 30;
p1.Gender = "Male";
p1.Birthday();
Console.WriteLine(p1.Age);
Console.ReadLine();
}
class Person
{
public string Name { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
public int Birthday()
{
int newAge = Age;
while (Age > 0)
{
newAge += 1;
break;
}
return newAge;
}
}
You have a couple issues with your code.
First you shouldnt be storing the "Age" of a person, you should be storing the Date they were born so that you can always calculate the Age.
public DateTime BirthDate { get; set; }
Second; consider the creation of a Person. In your code you create a new Person, then assign their Name, Gender and BirthDate properties. Is that really the best way of doing it? A Person has to have a Name, Gender and BirthDate right? Plus these properties don't change (or at least they shouldn't easily change). So make your Person class have a constructor accepting these arguments, and then make the setting of these properties private:
public string Name { get; private set; }
public string Gender { get; private set; }
public DateTime BirthDate { get; private set; }
public Person(string name, string gender, DateTime birthDate)
{
Name = name;
Gender = gender;
BirthDate = birthDate;
}
Then to calculate someone Age you can just compare the dates in a GetCurrentAge() method, then you can use your existing Age property but make it "read only" by just returning the value from GetCurrentAge():
public int Age => GetCurrentAge();
private int GetCurrentAge()
{
DateTime today = DateTime.Today;
int age = today.Year - BirthDate.Year;
if (BirthDate > today.AddYears(-age))
{
age--;
}
return age;
}
The code and calculation you are doing does not make sense but the bigger problem is that you should not store a calculated field. Instead store the date of birth and calculate the age. See also https://stackoverflow.com/a/1404/1260204 for how to calculate.
public class Person
{
public string Name { get; set; }
public string Gender { get; set; }
public DateTime BirthDate { get; set; }
public int Age
{ get {
// copied from https://stackoverflow.com/a/1404/1260204
var today = DateTime.Today;
var age = today.Year - BirthDate.Year;
if (birthdate > today.AddYears(-age)) {
age--;
}
return age;
}}
}
Calling the method
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "Frank";
p1.Age = 30;
p1.Gender = "Male";
p1.BirthDate = new DateTime(1986, 5, 12);
Console.WriteLine(p1.Age);
Console.ReadLine();
}
I'm studying object oriented programming. I have a class Dob, it reads the date of birth from main. If the date of birth from main was from 10 years ago until now, it says "error", else "verify".
Here is my class
public DateTime _Dob;
private DateTime dob {
get {
return _Dob;
}
set {
_Dob = value;
}
}
public Student(DateTime dob_) {
_Dob = dob;
}
public void checkdob(DateTime dob) {
DateTime local = DateTime.Now;
if (dob.Year >= local.Year - 10)) {
Console.WriteLine("error");
} else {
Console.WriteLine("verify");
}
Now I want to pass the birth date from main but I don't know how to do that. Here is what I have in main (It has errors and I don't know how to solve it):
Student dob = new Student(new DateTime(23/02/2010));
dob.checkdob( 02/12/2010);
Console.ReadLine();
First and foremost, you have the property just the wrong way around. The idea is that you expose the value of a private field through a public property, not the other way around:
private DateTime _dob;
public DateTime Dob
{
get { return _dob; }
set { _dob = value; }
}
But if you do not use the public property anyway, don't expose it.
Now, it seems strange to pass the date to the constructor of your class, and then pass it again when you want to check it. Use the value you already have.
public void CheckDdob()
{
if (_dob.Year >= DateTime.Now.Year -10))
{
Console.WriteLine("error");
}
else
{
Console.WriteLine("verify");
}
}
Then, to create a new DateTime for your constructor, just use the following:
Student dob = new Student(new DateTime(2010, 02, 23));
And finally, you may want to review your logic, because you do not actually check correctly if a date is more than 10 years ago. Then again, what you have may fit your requirements.
You will need to use a proper constructor parameter for DateTime. There are plenty of them listed here.
You can start with using this one,
new DateTime(2010,02,23)
Just an example on how to solve this:
using System;
public class Student
{
public Student(string name, DateTime dateOfBirth)
{
Name = name;
DateOfBirth = dateOfBirth;
}
public string Name { get; private set; }
public DateTime DateOfBirth { get; private set; }
}
public static class Helpers
{
public static bool IsOlderThen(this DateTime date, TimeSpan age)
{
var now = DateTime.UtcNow;
return now - date > age;
}
}
public class Program
{
public static void Main()
{
var adult = TimeSpan.FromDays(365 * 18);
var studentOld = new Student("Alice", DateTime.Parse("1998/04/17"));
var studentYoung = new Student("Bob", DateTime.Parse("2015/04/17"));
Console.WriteLine("isAdult: " + studentOld.DateOfBirth.IsOlderThen(adult));
Console.WriteLine("isAdult: " + studentYoung.DateOfBirth.IsOlderThen(adult));
}
}
I am beginner in programming and I want to ask you probably the easiest question.
I did something like this:
class person
{
private string name;
public string surname;
private int year;
}
class student : person
{
}
class Program
{
static void Main(string[] args)
{
List<student> list = new List<student>();
list.Add(new student()
{
surname = "jordan"
// name ... ???
// year .. ?
});
}
}
How can I correctly use get and set if I have private field or how can I assign a value to name or year?
You can set private property in constructor like this:
public class person
{
private string name { get; set; };
public string surname { get; set; };
private int year { get; set; };
public person(string name, int year)
{
this.name = name;
this.year = year;
}
}
public class student : person
{
public student(string name, int year) : base (name, year) { };
}
and use can be:
list.Add(new student("name", 45)
{
surname = "jordan"
});
(Note the use of Upper case for classes and properties, lower case reserved for fields and local variables).
Declare as public properties like so:
class Person
{
public string Surname {get; set;}
}
Usage:
new Person{
Surname = "jordan"
};
Or with private setters, and set in constructor.
class Person
{
public Person(string surname)
{
Surname = surname;
}
public string Surname {get; private set;}
}
Usage:
new Person("jordan");
Or private fields, also set in constructor (same usage).
class Person
{
private string surname;
public Person(string surname)
{
this.surname = surname;
}
public string Surname {get{return surname;}}
}
Even if the fields are private you can provide public properties. You should do that anyway since the fields should not be accessible from outside, all the more if they are just backing fields for properties.
class person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string surname;
public string Surname
{
get { return surname; }
set { surname = value; }
}
private int year;
public int Year
{
get { return year; }
private set { year = value; }
}
}
Now the fields are private and you can change the access modifiers of the properties according to your needs. You can even make the setter private as shown in the Year property.
List<Person> list = new List<Person>();
list.Add(new Person()
{
Name = "Michael",
Surname = "jordan",
});
Now you cannot modify the Year from outside since it's private. You could provide an appropriate constructor to initialize it.
What is the best approach for sorting a generic list when one of its objects property is changed?
I have the following example to help explain what is needed.
public class Sending
{
public Sending(int id, DateTime dateSent)
{
this.Id = id;
this.DateSent = dateSent;
}
public int Id { get; set; }
public DateTime DateSent { get; set; }
}
public class Operation
{
public List<Sending> ItemsSent = new List<Sending>();
public Operation()
{
ItemsSent.Add(new Sending(1, new DateTime(2010, 6, 2)));
ItemsSent.Add(new Sending(2, new DateTime(2010, 6, 3)));
ItemsSent[1].DateSent = new DateTime(2010, 6, 1);
}
}
What is the best way to trigger a sort on the list to sort by date after the DateSent property is set? Or should I have a method to update the property and perform the sort?
You could implement IComparable<Sending> on Sending and call Sort() on the ItemsSent. I would suggest to write a method to update an object and update the list manually.
public class Sending: IComparable<Sending>
{
// ...
public int CompareTo(Sending other)
{
return other == null ? 1 : DateSent.CompareTo(other.DateSend);
}
}
What you can do is you first implement INotifyChanged.
Then do some thing like this;
public class Sending : INotifyChanged
{
private int id;
private DateTime dateSent;
public Sending(int id, DateTime dateSent)
{
this.Id = id;
this.DateSent = dateSent;
}
public int Id { get; set; }
public DateTime DateSent
{
get
{
return this.dateSend;
}
set
{
this.dateSent = value;
OnPropertyChangerd("DateSent");
//CallYou List<Sending> Sort method;
}
}
So whenever a new value will set the sort method will sort the list.