2009-10-19 17 views
6

Lütfen koduna bir göz atın. Bir bakış elde etmek uzun sürmemeli. GetCourse() yanaListe <T> temizlendi sorunu

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 örneğindeki temel Course -list temizleyerek t.GetCourses().Clear(); çağrı, _items bir başvuru verir.

Bu davranışı önlemek istiyorum. Yani, GetCourse() bir liste döndürür, ancak bu değiştirilemez.

Bunu nasıl elde etmek için?

cevap

15

Listenin bir kopyasını oluşturabilir veya ReadOnlyCollection bunu sarabilirdiniz: İlk seçenek, bağımsız bir liste oluşturur

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

veya

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

- Arayan değişiklik mümkün olacak Öğeleri ekleme veya kaldırma, ancak bu değişiklikler öğretmen nesnesinin listesinde görünmeyecek. İkinci seçenek mevcut listenin etrafındaki sarıcıdır. Bu nedenle, koleksiyondaki herhangi bir değişiklik ambalajın içinden görünür olacaktır. Arayan koleksiyonda herhangi bir değişiklik yapamaz. listede tarafından başvurulan Course nesneler varsa her iki durumda da, kendi veri değişti

Not, bu değişiklikler görülebilir her iki şekilde olacak - bu olay durdurmak istiyorsanız her Course klonlamak gerekirdi.

+0

Bu şimdi C# ile bitti mi? C# döngüsünden çıktım ama böyle yeni bir liste yapar mısın yoksa bir şekilde listeyi klonlar mıydın? Listenin listeyi derinlemesine kopyalamak için bir yöntem içerdiğinden şüphelenirim. –

+2

@Thomas: Derin bir klon oluşturmak için ' List'te bir şey olduğunu sanmıyorum. Klonlama benim tecrübemde büyük ölçüde cesaret kırmadı. –

5

Nasıl bir IEnumerable<Course> döndürme hakkında?

Biraz konu dışı

: Gerçekten vesaire, ilave silinebilir bir liste iade etmek istiyorsunuz, muhtemelen belki yerine List<T> ait Collection<T> veya arayüzleri hatta bir dönmelidir, örneğin ICollection<T>. Genel olarak, her zaman mümkün olan en kısıtlayıcı türünü geri döndürmeniz gerektiğini söyleyebilirim, çünkü daha sonra daraltmaktan daha kolay olan şeyleri gevşetmek daha kolaydır.

+0

Bir arayan kişi bunu List 'a geri yükleyebilir ve yine de alttaki listeyi değiştirebilir. –