tti*_*tto 3 c# oop properties list
我现在正在学习面向对象编程,但我在练习中遇到了问题。我有一个有学生的学校班级。同一班级的学生人数不得相同。我有以下内容:
class SchoolClass
{
private List<Student> students;
public List<Student> Students
{
get { return this.students; }
set
{
if (value == null) throw new ArgumentNullException("Students list can not be null!");
if (value.Select(n => n.Number).Distinct().Count() != value.Count())
throw new ArgumentException("There are students in the list with the same class number!");
this.students = value;
}
}
public SchoolClass( List<Student> students)
{
this.Students = students;
}
}
class Student
{
private uint number;
public uint Number
{
get { return this.number; }
set
{
if (value == 0) throw new ArgumentException("Student's number can not be null!");
else this.number = value;
}
}
public Student(string name, uint number)
{
this.Number = number;
}
}
Run Code Online (Sandbox Code Playgroud)
当我在 Main() 类中初始化具有相同编号的两个学生时,出现 ArgumentException("列表中存在具有相同班级编号的学生!"); 正如预期的那样。但是,当我有一个 SchoolClass (sc) 实例并调用其学生列表并使用 Add() (sc.students.Add(new Student(..)) 时,我可以插入一个具有重复编号的学生。同样的情况List.InsertAt() 方法。我读到可以使用 ReadOnlyCollection<...>(...) 或 AsReadOnly() 来只读获取 getter,但是在这种情况下我将如何将新学生添加到列表中?
避免/解决此问题的最佳实践是什么?
您不应该在您的类上公开 List<> 属性 - 这几乎从来都不是一个好主意,因为它使类的用户对您的数据有太多的控制权,在这种情况下它当然不是一个好的选择。相反,您应该仅公开您需要的属性,并执行您自己的验证:
// store the students as a List<>...
private List<Student> students;
// ...but expose them as IEnumerable<>.
public IEnumerable<Student> Students
{
get { return this.students; }
}
// IEnumerable<> does not allow adding, removing, clearing, etc -
// you know you're the only one altering the data
// and you can choose to give them restricted access with your own
// validation logic
public void AddStudent(Student student)
{
if (this.students.Any(s => s.Number == student.Number))
throw new ArgumentException("Duplicate student number!");
this.students.Add(student);
}
Run Code Online (Sandbox Code Playgroud)