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();
}
Related
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-
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));
}
}
Hello I'm trying to raise an event when the Birthdate of a person is greater then the actual date.
I'm new with events and it doesn't seem to work.
Code is beneath,
namespace LibClassLuchthaven
{
public class Person
{
public DateTime Birthdate { get; set; }
public string Firstname { get; set; }
public Gender Gender { get; set; }
public string Name { get; set; }
public event EventHandler BirthdateInFuture;
public Person()
{
this.Birthdate = DateTime.Now;
this.Firstname = string.Empty;
this.Gender = Gender.unknown;
this.Name = string.Empty;
}
public Person(DateTime birthdate, string firstname, Gender gender, string name)
{
this.Birthdate = birthdate;
this.Firstname = firstname;
this.Gender = gender;
this.Name = name;
}
public void OnBirthdateInFuture()
{
if (BirthdateInFuture!=null)
{
if (this.Birthdate > DateTime.Now)
{
BirthdateInFuture(this, EventArgs.Empty);
}
}
}
public override string ToString()
{
return this.Name + ", " + this.Firstname + " - " + this.Birthdate + " ( +" + this.Gender + ")";
}
}
}
public partial class FormCrewManagement : Form
{
public Person person = new Person();
public FormCrewManagement()
{
InitializeComponent();
person.BirthdateInFuture += Person_BirthdateInFuture;
}
private void Person_BirthdateInFuture(object sender, EventArgs e)
{
MessageBox.Show("Birthdate is in the future");
}
Try Changing the Property
public DateTime Birthdate { get; set; }
to
private DateTime _birthDate;
public DateTime Birthdate
{
get {return _birthDate;}
set
{
_birthDate=value;
if(value > DateTime.Now)
BirthdateInFuture?.Invoke(this, EventArgs.Empty);
}
}
This will raise the event when Birthdate value is in future.
Philip,
there is no place in your code where the event is raised. You could create a property called BirthDate and in the setter part, raise the event. When the birthdate is changed to a future date, it would/could raise the event.
It looks like the problem may be a logical one, rather than anything to do with events. You are setting the birthday to today's date... then checking if it's later. It never will be.
public Person()
{
this.Birthdate = DateTime.Now;
if (BirthdateInFuture!=null)
{
if (this.Birthdate > DateTime.Now)
{
BirthdateInFuture(this, EventArgs.Empty);
}
}
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.
I am building some tiny lib, and I have run into a problem.
I want to provide a two-way solution, for example:
How can I accomplish this?
I am getting exception thrown, because it expects something... Any example that will do is welcomed :) Thanks!
EDIT: I am executing something, initially my code is similar to this one:
System.IO.DriveInfo d = new System.IO.DriveInfo("C:");
I want to achieve with my class the following:
Driver d = new Driver();
d.DriverLetter = "C:";
And still get the same results, I use ManagementObjectSearch, ManagementObjectCollection and some other System.Management classes.
You need to provide both constructors:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Country { get; set; }
// Paramterless constructor - for new Person();
// All properties get their default values (string="" and int=0)
public Person () { }
// Parameterized constructor - for new Person("Joe", 16, "USA");
public Person (string name, int age, string country)
{
Name = name;
Age = age;
Country = country;
}
}
If you define a parameterized constructor, the default parameterless constructor is not included for you. Therefore you need to include it yourself.
From MSDN 10.10.4 Default constructors:
If a class contains no instance constructor declarations, a default instance constructor is automatically provided.
You have to define a constructor that takes those three arguments:
public class Person
{
public Person(string name, string age, string country)
{
this.Name = name;
this.Age = age;
this.Country = country;
}
}
This way, you can assign the values to the properties when the class is constructed. You can have more than one constructor for a class taking different parameters and you can have one constructor call another constructor with : this() syntax:
public class Person
{
public Person()
: this(string.Empty, string.Empty, string.Empty)
{
}
public Person(string name, string age, string country)
{
this.Name = name;
this.Age = age;
this.Country = country;
}
}
Here the "empty" constructor will call the other constructor and set all properties to empty strings.
Try this:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Country { get; set; }
public Person()
{
}
public Person(string name, int age, string country)
{
Name = name;
Age = age;
Country = country;
}
}
class Test
{
static void Main(string[] args)
{
var person1 = new Person();
person1.Name = "Joe";
person1.Age = 2;
person1.Country = "USA";
var person2 = new Person("John", 4, "USA");
}
}
The .NET Framework will implicitly provide a default/parameterless constructor if you don't define a constructor. If you define a parameterized constructor, though, you need to explicitly define a default constructor too.
You probably missing your Age property type as int or string.
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Country { get; set; }
public Person()
{
}
public Person(string name, int age, string country)
{
this.Name = name;
this.Age = age;
this.Country = country;
}
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person("Erik", 16, "United States");
Person p2 = new Person();
p2.Name = "Erik";
p2.Age = 16;
p2.Country = "United States";
}
}
EDIT: Also you need parameterless constructor for also.