I have a class with some private and public fields and properties.
[MessagePackObject(false)]
public class Person
{
[Key(1)]
public string Name { get; set; }
[IgnoreMember]
private int _age;
[Key(2)]
public int Age { get { return _age; } set { _age = value; } }
}
In some cases I don't need to serialize Age, I need to serialize only some fields (for example only Name). So I need 2 methods, to serialize all object and partial serialize. How can I organize it?
Answering to my own question.
The only solution I have found is to move Name to base class BasePerson. I will serialize object as BasePerson and then deserialize bytes to Person
[MessagePackObject(false)]
public class BasePerson
{
[Key(1)]
public string Name { get; set; }
}
[MessagePackObject(false)]
public class Person
{
[IgnoreMember]
private int _age;
[Key(2)]
public int Age { get { return _age; } set { _age = value; } }
}
Usage:
Person person = new Person()
{
Name = "Gor",
Age = 26
};
var serializedBytes = MessagepackSerializer.Serialize<BasePerson>(person);
// will give me person with `Name` "Gor" and `Age` 0 (default value of int)
var personWithoutAge = MessagepackSerializer.Deserialize<Person>(serializedBytes );
Related
I am trying to learn OOP by creating a small program that reads a list of people and outputs only those who are older than 30 using two classes Person and PollParticipant. I am instantiating a new person from my person class and adding name and age:
Person person = new Person(name,age);, which are defined in a constructor, but when I do so it gives me an error that the name 'name' does not exist in the current context. My fields are set to public, so it should be able to access them, what am I doing wrong?
Here is my Person class:
namespace Poll_Opinion
{
public class Person
{
public string name;
public int age;
public Person(string name, int age)
{
this.name = Name;
this.age = Age;
}
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
}
}
}
}
My poll participants class:
namespace Poll_Opinion
{
class PollParticipant
{
public List<Person> pollParticipant;
public PollParticipant()
{
this.pollParticipant = new List<Person>();
}
public void AddMember(Person participant)
{
this.pollParticipant.Add(participant);
}
public Person ShowOlderMembers()
{
return this.pollParticipant.OrderByDescending(p => p.age).First();
}
}
}
And my Program.cs where I make the instantiation:
namespace Poll_Opinion
{
class Program
{
static void Main(string[] args)
{
PollParticipant pollparticipant = new PollParticipant();
int n = int.Parse(Console.ReadLine());
for (int i = 0; i < n; i++)
{
string[] input = Console.ReadLine().Split();
int age = int.Parse(input[i]);
Person person = new Person(name,age);
pollparticipant.AddMember(person);
}
}
}
}
You have two issues. The first is here:
Person person = new Person(name,age);
You try to pass name and age to the Person constructor but you have not instantiate them.
The second problem is in your constructor:
public Person(string name, int age)
{
// this.name = Name;
this.name = name;
// this.age = Age;
this.age = age;
}
You need to assign name parameter to this.name field, not Name property. In you case you assign this.name to this.name:
this.name = Name; // => where 'Name' get method return this.name
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
By the way, you don't need a public field name (that should be private) in this case. Just do:
public string Name { get; set; }
In C# the properties pratically already have an hidden private field.
name is not defined in your Main() function when you are creating the Person objects.
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
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.
Can I create an object from class person inside a class employee and access to the methods and members of class person through employee class using the person’s object that I created in class employee
public class Person
{
protected string _name;
public int _age;
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
}
class Employee
{
Person person = new Person();
}
Do you mean this?
public class Employee
{
private Person person = new Person();
public string Name
{
get { return person.Name; }
set { person.Name = value; }
}
public int Age
{
get { return person.Age; }
set { person.Age = value; }
}
}
You could do:
class Employee
{
Person person = new Person();
public string Name
{
get { return person.Name; }
set { person.Name = value }
}
public int Age
{
get { return person.Age; }
set { person.Age = value; }
}
}
You could look at providing a 'person' interface and letting the employee class implement it.
Yes, because class Person is public.
I have two classes named Person and Staff. Person class just keeps fields and properties. Staff class implements IEnumarable interface. What I want to do is to make this class enumarable. I will create an instance Staff class on form_Load and then iterate over it. But I think something is wrong here.
public Person this[int index]
{
get { return Staff[index]; }
set { Staff[index] = value; }
}
This is what I have so far. How can I fix this
public class Person
{
private int _age;
private string _name;
public int Age
{
get { return _age; }
set { _age = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public Person(int age, string name)
{
_age = age;
_name = name;
}
}
public class Staff : IEnumerable
{
private List<Person> list;
public Person this[int index]
{
get { return Staff[index]; }
set { Staff[index] = value; }
}
public Staff(Person person)
{
list = new List<Person>();
list.Add(person);
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < list.Count; i++)
{
yield return list[i];
}
}
}
Syntax errors indeed. This would work though:
static void Main(string[] args)
{
var staff = new Staff();
staff.AddPerson(new Person(12, "John Doe"));
staff.AddPerson(new Person(12, "Jande Doe"));
foreach (var person in staff)
{
Console.WriteLine(person.Name);
}
Console.ReadLine();
}
}
public class Person
{
public int Age { get; private set; }
public string Name { get; private set; }
public Person(int age, string name)
{
Name = name;
Age = age;
}
}
public class Staff : IEnumerable<Person>
{
private List<Person> staff = new List<Person>();
public void AddPerson(Person p)
{
this.staff.Add(p);
}
public IEnumerator<Person> GetEnumerator()
{
return this.staff.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.staff.GetEnumerator();
}
}
I'm getting the impression that you want to enumerate the collection of persons through the staff class. You can do that by implementing IEnumerable and return the enumerator of the people list. So that's what I did.
I implemented IEnumerable to return a strongly typed enumerator and shortened some of your code. Hope it helps.