2009-10-19 6 views
6

コードをご覧ください。垣間見るのは時間がかかりません。 GetCourse()のでリスト<T>が解決されました。

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

Teacherインスタンス内の基礎Course -listをクリアさt.GetCourses().Clear();を呼び出し、_itemsの参照を返します。

この現象を防止します。つまり、GetCourse()はリストを返しますが、変更可能ではありません。

これを達成する方法は?

答えて

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

を最初のオプションは、独立したリストを作成する - 呼び出し側はそれを変更することができるようになりますアイテムを追加または削除しても、その変更は教師オブジェクトのリストには表示されません。 2番目のオプションは、既存のリストを囲むラッパーに過ぎません。そのため、コレクションに対する変更はすべてラッパーを通じて表示されます。呼び出し元はコレクションを変更することはできません。

どちらの場合も、リストで参照されているオブジェクトのデータが変更されている場合は、その変更が表示されます。その場合は、それぞれをCourseにクローンする必要があります。

+0

これはC#で今行われていますか?私はC#ループを抜けていますが、そのような新しいリストを作成するか、どういうわけかリストをクローンしますか?リストにディープコピーする方法が含まれていると思われます。 –

+2

@Thomas:深いクローンを作成するために 'List 'には何もないと思います。私の経験では、クローニングはほとんどお勧めできません。 –

5

代わりにIEnumerable<Course>を返すのはどうですか?ちょっとオフトピック

あなたが本当にエトセトラ、クリアに追加することができるリストを返すようにしたいならば、あなたはおそらくList<T>、またはインターフェイスの多分1の代わりにCollection<T>を返す必要があり、例えば、ICollection<T>。一般的には、できる限り最も制限の厳しいタイプを返すべきだと言います。後で絞り込むよりも、そのようなことを緩めるほうが簡単だからです。

+0

発信者はそれをリストにキャストしても、依然として下位のリストを変更できます。 –

関連する問題