class ProjectGroup
{
private List<string> members = new List<string>();
public List<string> Members { get { return members; } }
}
class Course
{
public bool AddStudent(string name)
{
ProjectGroup projectGroup = new ProjectGroup();
projectGroup.Members.Add(name);
return true;
}
}
So in this code I created a private list of members
and accessed it with a public list Members
which makes no sense for being a private in the first place. So instead I made a clone of the private list ToArray()
.
class ProjectGroup
{
private List<string> members = new List<string>();
public string[] Members { get { return members.ToArray(); } }
}
but that means I can't use projectGroup.Members.Add(name);
anymore since Members
is an array now.
How can I add string name
to projectGroup.Members
now?
CodePudding user response:
The first code makes perfect sense. It's a read-only property so you can get the List
object in order to add items or whatever but you cannot set the property, so you cannot replace the existing List
with a completely different one. The thing is, you don't need the field at all. Just use the property:
public List<string> Members { get; } = new List<string>();
There will be a field created implicitly by the compiler but you don't need to use it so you don't need to declare it explicitly.
CodePudding user response:
but that means I can't use
projectGroup.Members.Add(name);
anymore since Members is an array now.
How can I add string name to
projectGroup.Members
now?
It depends, you should ask yourself, will this ProjectGroup.Members
changed over time or only populated once at creation time? Is the encapsulation actually worth the trouble?
Populated Once
If it populated once, you can use constructor. This way you can ensure the members
is read-only.
class ProjectGroup
{
private List<string> members;
public string[] Members { get { return members.ToArray(); } }
public ProjectGroup(List<string> projectMembers)
{
//Ensure projectMembers cant be null
if(projectMembers == null)
throw new ArgumentNullException("projectMembers");
members = projectMembers;
}
}
You can then create an instance of the ProjectGroup
this way:
var pg = new ProjectGroup(new List<string>(){"robert", "bob"});
Restricting Operations
If you want to limit the number of action you can do on the List<string>
, you can add methods to expose the functionality you required. For example, let's say we want to validate name before being added into the members
. You can add a method in ProjectGroup
to do so (lets call it AddName
).
class ProjectGroup
{
private List<string> members = new List<string>();
public string[] Members { get { return members.ToArray(); } }
public void AddName(string name)
{
//Ensure name is never empty string or null
if(string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException("name");
members.Add(name);
}
}
You can then add more members as such:
var pg = new ProjectGroup();
pg.AddName("alice");
pg.AddName("sarah");
You can create method for member removal in the similar fashion.