List <T> fixes the problem

Please take a look at the code. It does not take long to peek.

class Teacher { private int _id; public int ID { get { return _id; } set { _id = value; } } private string _message; public string Message { get { return _message; } set { _message = value; } } public Teacher(int id, string msg) { _id = id; _message = msg; } private List<Course> _items; public List<Course> GetCourses() { return _items; } public Teacher() { if (_items == null) { _items = new List<Course>(); } _items.Add(new Course(1, "cpp")); _items.Add(new Course(1, "java")); _items.Add(new Course(1, "cs")); } public void Show() { Console.WriteLine(this._id); Console.WriteLine(this._message); } public void ShowList() { foreach(Course c in _items) { c.Show(); } } } class Course { private int _id; public int ID { get { return _id; } set { _id = value; } } private string _message; public string Message { get { return _message; } set { _message = value; } } public Course(int id, string msg) { _id = id; _message = msg; } private List<Teacher> _items; public List<Teacher> GetTeachers() { return _items; } public Course() { if(_items == null) { _items = new List<Teacher>(); } _items.Add(new Teacher(1, "ttt")); _items.Add(new Teacher(1, "ppp")); _items.Add(new Teacher(1, "mmm")); } public void Show() { Console.WriteLine(this._id); Console.WriteLine(this._message); } public void ShowList() { foreach (Teacher t in _items) { t.Show(); } } } class Program { static void Main(string[] args) { Teacher t = new Teacher(); t.ID = 1; t.Message = "Damn"; t.Show(); t.ShowList(); t.GetCourses().Clear(); t.Show(); t.ShowList(); Console.ReadLine(); } } 

Since GetCourse() returns a link to _items, calling t.GetCourses().Clear(); clears the base Course -list in the Teacher instance.

I want to prevent this behavior. That is, GetCourse() will return a list, but it will not change.

How to do it?

+6
list c #
source share
2 answers

You can create a copy of the list or wrap it in ReadOnlyCollection:

 private List<Course> _items; public IList<Course> GetCourses() { return new List<Course>(_items); } 

or

 private List<Course> _items; public IList<Course> GetCourses() { return new ReadOnlyCollection<Course>(_items); } 

The first parameter creates an independent list - the caller can change it, add or remove elements, but these changes will not be displayed in the list of teacher objects. The second option is just a wrapper around the existing list, so any changes to the collection will be visible through the shell. The caller cannot make any changes to the collection.

Please note that in both cases, if the Course objects referenced by the list have their own data, these changes will be visible in any case - you will need to clone each Course if you want to stop it.

+15
source share

What about returning an IEnumerable<Course> instead?

Disable topic: If you really want to return a list that can be added, cleared, etc., most likely you should return Collection<T> instead of List<T> , or perhaps even one of the interfaces, for example ICollection<T> . In general, I would say that you should always return the most restrictive type that you can, since it is easier to loosen such things than to narrow it down later.

+5
source share

All Articles