I have a class and I am using it inside a LIST
List<user> listWithCustomClass = List<user>();
myClass.cs
public class user
{
public user(string fullname, string city, string state, int age, int type)
{
name = fullname;
citi = city;
estate = state;
tipe = type;
}
private string name = string.Empty;
private string citi = string.Empty;
private string estate = string.Empty;
private int tipe = 0;
public string getFullname
{
get { return name; }
set { name = value;}
}
public string getCity
{
get { return citi; }
set { citi = value;}
}
public string getState
{
get { return state; }
set { state = value;}
}
public int getType
{
get { return type; }
set { type = value;}
}
}
How can I add a custom toString() without having to override generic toString(). I would like to add something like showDate().
For example, in a combobox I would like the output of the inserted information to be:
--> Hello, your name is {name} and your age is {age}
Like this:
foreach(var item in user)
{
user.ShowData();
}
Add this in your class:
public string ShowData()
{
return "Hello, your name is " + name + " and your age is " + age.ToString();
}
but you must also define age first. Which, following your style, would be:
private int age = 0;
and then in the constructor add:
this.age = age;
EDIT
foreach(var item in listWithCustomClass)
{
item.ShowData();
}
Related
I have a class, below:
public Person(string name, int age)
{
Name = name;
Age = age;
}
After the class is declared, I have the following:
String OtherName;
Int OtherAge;
Person jane = new Person("Jane", 28);
OtherName = Jane.Name;
OtherAge = Jane.Age;
How do I store OtherName and OtherAge in such a way that they do not change when I change the value of jane?
The variables OtherName and OtherAge, as it stands, are going to keep their values, even if the value of jane, or its properties, are updated.
I refactor Person class in the following, If name changes, other name will change. But Other name could change not to effect name prop.
public class Person
{
public Person(string name, int age)
{
Name = name;
Age = age;
}
private string name;
public string Name
{
get { return name; }
set { otherName = name = value; }
}
private int age;
public int Age
{
get { return age; }
set { otherAge = age = value; }
}
private string otherName;
public string OtherName
{
get { return otherName; }
set { otherName = value; }
}
private int otherAge;
public int OtherAge
{
get { return otherAge; }
set { otherAge = value; }
}
}
Example:
static void Main(string[] args)
{
Person jane = new Person("Jane", 28);
jane.OtherName = jane.Name;
jane.OtherAge = jane.Age;
jane.Name = "Dave";
jane.Age = 30;
Console.WriteLine(jane.Name);
Console.WriteLine(jane.Age);
Console.WriteLine(jane.OtherName);
Console.WriteLine(jane.OtherAge);
Console.ReadKey();
}
Output:
Dave
30
Dave
30
In C# properties, where is the 'value' variable defined? I can see it used in the bodies of setters before it is defined anywhere.
namespace TestBindings
{
public class Dog
{
private decimal age;
private string name;
private const int AgeFactor = 7;
public Dog(decimal age, string name)
{
this.age = age;
this.name = name;
}
public decimal AgeDogYears
{
get { return age / AgeFactor; }
set { age = value * AgeFactor; }
}
public decimal AgeHumanYears
{
get { return age; }
set { age = value; } //here
}
public string Name
{
get { return name; }
set { name = value; } // and here
}
}
}
The 'value' variable is automatically passed in from the use-site and is a pre-defined variable name for the value passed in the set expression.
e.g.
var jack = new Dog(13, "jack");
jack.Name = "Jackson";
Here the value after the = sign is being passed into the setter defined in the class as 'value'.
public string Name
{
get { return name; }
set { name = value; } //here
}
It's roughly equivalent to the Java expression it replaces of having an explicit getter and setter method, just using different syntax in order to unify settings fields and properties.
e.g.
public class Dog {
private double age;
private String name;
private final int AgeFactor = 7;
public Dog(double age, String name) {
this.age = age;
this.name = name;
}
public double getAgeHumanYears() {
return age;
}
public void setAgeHumanYears(double value) {
this.age = value;
}
public double getAgeDogYears() {
return age / AgeFactor;
}
public void setAgeDogYears(double value) {
age = value * AgeFactor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
With our test changing to.
private Dog jack = new Dog(13, "jack");
jack.setName("Jackson");
My constructor get info from the form. The 'name' is addressed with 'aName' (from the constructor), then there has to be a check done with prop 'NameCheck'. but if I compile it, it return an empty string. Any ideas?
Code:
---- Class ----
//Fields
private List<Create> Characters;
private string name;
private int health;
private int mSpeed;
private Role role;
private Speciality speciality;
//Properties
public string NameCheck
{
get {
return name;
}
set
{
if (string.IsNullOrEmpty(name))
{
name = "Name not specified";
}
else
{
name = value;
}
}
}
//Constructor
public Create(string aName, int aHealth, int aMSpeed, Role aRole, Speciality aSpeciality)
{
this.name = aName;
this.health = aHealth;
this.mSpeed = aMSpeed;
this.role = aRole;
this.speciality = aSpeciality;
Characters = new List<Create>();
}
---- Form ----
Create character = new Create(tbName.Text, health, mspeed, aLane, aSpecial);
Characters.Add(character);
cbSummary.Items.Add(character.ToString());
PS: cbSummary is a combobox.
EDIT:
public override string ToString()
{
return "Name: " + NameCheck + " - Health: " + health + " - MovementSpeed: " + mSpeed + " - Role: " + role + " - Speciality: " + speciality;
}
You should set this.NameCheck instead of this.name in your constructor
public Create(string aName, int aHealth, int aMSpeed, Role aRole, Speciality aSpeciality)
{
this.NameCheck = aName;
also you should check value for emptiness or being null instead of name in your property setter
set
{
if (string.IsNullOrEmpty(value))
{
You have a small typo in your property:
public string NameCheck
{
get {
return name;
}
set
{
// You need to check value, not name.
if (string.IsNullOrEmpty(value))
{
name = "Name not specified";
}
else
{
name = value;
}
}
}
In your constructor you should use your NameCheck property rather than the name field:
public Create(string aName, int aHealth, int aMSpeed, Role aRole, Speciality aSpeciality)
{
this.NameCheck = aName;
this.health = aHealth;
this.mSpeed = aMSpeed;
this.role = aRole;
this.speciality = aSpeciality;
Characters = new List<Create>();
}
Also as Paddy said you are doing an incorrect check in the set body of NameCheck:
public string NameCheck
{
get
{
return name;
}
set
{
if (string.IsNullOrEmpty(value))
{
name = "Name not specified";
}
else
{
name = value;
}
}
}
I am trying to get and send a list of this object to a text file. The text file is in the following format.
name,IDnumber,department,value
there are quite a few lines of this so i used a for to read them in.
This is the code for the read and write to the file.
public List<Employee> ReadFile(string fileName) {
StreamReader fileIn = new StreamReader(fileName);
fileIn = File.OpenText(fileName);
List<Employee> list = new List<Employee>();
string[] test;
string name;
string ID;
string dep;
string post;
while (!fileIn.EndOfStream || !File.Exists(fileName)) {
string inString = fileIn.ReadLine();
test = inString.Split('#');
name = test[0];
ID = test[1];
dep = test[2];
post = test[3];
Employee newEmp = new Employee(name, ID, dep, post);
list.Add(newEmp);
}
fileIn.Close();
return list;
}
public void WriteFile(List<Employee> outList, string file) {
StreamWriter writeOut = new StreamWriter(file);
for (int i = 0; i < outList.Count; i++) {
writeOut.WriteLine(outList[i].name + '#' + outList[i].IDnum + '#' + outList[i].department + '#' + outList[i].position);
}
writeOut.close();
}
This is the code for my class. The error is being thrown at the set.
public class Employee {
public string name { get { return name; } set { name = value; } }
public string IDnum { get { return IDnum; } set { IDnum = value; } }
public string department { get { return department; } set { department = value; } }
public string position { get { return position; } set { position = value; } }
public Employee() {
name = string.Empty;
IDnum = string.Empty;
department = string.Empty;
position = string.Empty;
}
public Employee(string newName, string newID) {
name = newName;
IDnum = newID;
department = string.Empty;
position = string.Empty;
}
public Employee(string newName, string newID, string newDep, string
newPost) {
name = newName;
IDnum = newID;
department = newPost;
position = newDep;
}
}
I am not sure if there is some kind of formatting that I am missing for the set function to function as needed. The This is the function i am calling for the in and out of the file. I believe that it is never making it to the out so it is likely how i am importing the data.
It's a really common gotcha... a C# rite of passage!
Let's take a look at a single property (this applies to all of your properties though)...
public string name { get { return name; } set { name = value; } }
so what happens when you try myObj.name = "foo";?
In the set method, you refer back to the very same property name. So it tries to access name, which goes around again (and again, and again, recursively until you StackOverflow).
A backing field with proper naming conventions is the norm here:
private string name;
public string Name{get { return name; } set{ name = value; }}
or even better, if there's no logic involved, an auto-property.
public string Name{ get; set; }
You keep calling IDnum and other properties over and over recursively, until the stack overflows
public string IDnum { get { return IDnum; } set { IDnum = value; } }
When you do something like
IDnum = someValue;
that calls the setter for IDnum, which runs the code in the setter
IDnum = value
Which in turn calls the setter of IDnum, until you run out of stack.
The Fix
In your case, it looks like you can use automatic properties
public string IDnum { get; set; }
You should change
public string name { get { return name; } set { name = value; } }
public string IDnum { get { return IDnum; } set { IDnum = value; } }
public string department { get { return department; } set { department = value; } }
public string position { get { return position; } set { position = value; } }
to
public string name { get; set; }
public string IDnum { get; set; }
public string department { get; set; }
public string position { get; set; }
or introduce backing fields:
private string _name;
public string name { get { return _name; } set { _name = value; } }
See https://msdn.microsoft.com/en-us/library/bb384054.aspx for more info on Auto-Implemented Properties in C#.
Please note, that the commonly used naming of public properties is PascalCasing. Your properties in PascalCasing would look like this:
public string Name { get; set; }
public string IdNum { get; set; }
public string Department { get; set; }
public string Position { get; set; }
How can I get all the property of the following class:
public class Employee
{
int employeeID;
string lastName; // should be (20) chars only
string firstName; // should be (10) chars only
string title; // should be (30) chars only
string address; // should be (60) chars only
string city; // should be (15) chars only
string region; // should be (15) chars only
string postalCode; // should be (10) chars only
string country; // should be (15) chars only
string extension; // should be (4) chars only
string homePhone;
public int EmployeeID
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
public string Title
{
get
{
return title;
}
set
{
title = value;
}
}
public string Address
{
get
{
return address;
}
set
{
address = value;
}
}
public string City
{
get
{
return city;
}
set
{
city = value;
}
}
public string Region
{
get
{
return region;
}
set
{
region = value;
}
}
public string PostalCode
{
get
{
return postalCode;
}
set
{
postalCode = value;
}
}
public string Country
{
get
{
return country;
}
set
{
country = value;
}
}
public string Extension
{
get
{
return extension;
}
set
{
extension = value;
}
}
public string HomePhone
{
get { return homePhone; }
set { homePhone = value; }
}
}
I tried to use reflection/PropertyInfo but with slight problem, the data type is including in the list:
public PropertyInfo[] getPropertyInfo()
{
PropertyInfo[] propertyInfos;
propertyInfos = typeof(Employee).GetProperties();
return propertyInfos;
}
Thank you in advance.
Your method returns a PropertyInfo data structure for each property, which includes information such as the property name, the property return type, etc. If you just want the name, access the Name property.
To map an array of PropertyInfos to a collection of the property names, the LINQ Select extension method can be used:
var propertyNames = getPropertyInfo().Select(p => p.Name).ToList();
PS: You might consider using auto-implemented properties to reduce the amount of code in your class:
...
public string LastName { get; set; } // should be (20) chars only
public string FirstName { get; set; } // should be (10) chars only
...