代码之家  ›  专栏  ›  技术社区  ›  user366312

list<t>is cleared problem

  •  6
  • user366312  · 技术社区  · 15 年前

    请看一下密码。不需要很长时间就可以看一眼。

    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();
            }
        }
    

    自从 GetCourse() 返回对\项的引用,调用 t.GetCourses().Clear(); 正在清除基础 Course -列表中 Teacher 实例。

    我想阻止这种行为。也就是说, GETCAREL() 将返回一个列表,但不可修改。

    如何做到这一点?

    2 回复  |  直到 15 年前
        1
  •  15
  •   Jon Skeet    15 年前

    您可以创建列表的副本,或者将其包装在readOnlyCollection中:

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

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

    第一个选项创建一个独立的列表-调用者可以修改它,添加或删除项目,但是这些更改不会显示在教师对象的列表中。第二个选项只是围绕现有列表的包装器,因此对集合的任何更改都将通过包装器可见。调用方将无法对集合进行任何更改。

    注意,在这两种情况下,如果 Course 列表引用的对象的数据已更改,这些更改将以任何方式可见-您必须克隆每个对象 课程 如果你想阻止这种情况的发生。

        2
  •  5
  •   Svish    15 年前

    还一个怎么样 IEnumerable<Course> 相反?

    稍微偏离主题: 如果您真的想返回一个可以添加、清除等的列表,那么您应该返回一个 Collection<T> 而不是 List<T> 或者可能是其中一个接口,例如 ICollection<T> . 一般来说,我会说您应该总是返回尽可能严格的类型,因为这样的事情比以后缩小范围更容易放松。

    推荐文章