2012-10-30 10 views
12

Więc mam w sobie klasę i ogólną listę, ale jest prywatna.Jak zrobić klasy jako IEnumerable w języku C#?

class Contacts 
{ 
    List<Contact> contacts; 
    ... 
} 

Chcę uczynić pracę klasy jak byłoby to zrobić:

foreach(Contact in contacts) .... ; 

tak (nie działa):

Contacts c; 
foreach(Contact in c) .... ; 

W powyższym przykładzie Kontakt klasa instancji C ma zwrócić każdy przedmiot z kontaktów (prywatny członek c)

Jak to zrobić? Wiem, że to musi być niezliczona stopa zwrotu, ale gdzie to zadeklarować?

Odpowiedz

19

Wdrożenie interfejsu IEnumerable:

class Contacts : IEnumerable<Contact> 
{ 
    List<Contact> contacts; 

    #region Implementation of IEnumerable 
    public IEnumerator<Contact> GetEnumerator() 
    { 
     return contacts.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
    #endregion 
} 
+0

Jaka jest różnica między nimi? –

+0

@John: Pomiędzy tymi dwiema metodami? Jedna to implementacja IEnumerable, a jedna jest IEnumarable <>. Kiedy zaimplementujesz IEnumarable <>, musisz także zaimplementować IEnumarable. – LightStriker

+0

Ale otrzymuję ten błąd na drugiej metody "Contacts.IEnumerable.GetEnumerator()": zawierający typ nie implementuje interfejsu "System.Collections.IEnumerable" –

5
public class Contacts: IEnumerable 
{ 
    ...... 
    public IEnumerator GetEnumerator() 
    { 
     return contacts.GetEnumerator(); 
    } 
} 

powinien zrobić trick dla Ciebie.

+0

Nie kompiluje ani ... – Virus721

10

Albo zwracać IEnumerator<Contact> przez dostarczenie sposobu GetEnumerator:

class Contacts 
{ 
    List<Contact> contacts; 

    public IEnumerator<Contact> GetEnumerator() 
    { 
     foreach (var contact in contacts) 
      yield return contact; 
    } 
} 

foreach szuka GetEnumerator. Spojrzeć tutaj szczegóły dotyczące specyfikacji języka to: https://stackoverflow.com/a/3679993/284240

How to make a Visual C# class usable in a foreach statement

+0

@ TimeSchmelter: A w jaki sposób foreach dowie się, że ta klasa implementuje metodę GetEnumerator, jeśli nie ma interfejsu do deklaracji umowy implementacyjnej? – LightStriker

+2

@ Marc-AndréJutras: 'foreach' szuka 'GetEnumerator'. Sprawdź szczegóły specyfikacji języka: http://stackoverflow.com/a/3679993/284240 –

+0

Intersting. Zawsze wydawało się, że interfejs jest obowiązkowy. Dobrze wiedzieć. "Wadą pominięcia IEnumerable i IEnumerator jest to, że klasa kolekcji nie jest już interoperacyjna z instrukcjami foreach lub odpowiednikami innych języków zgodnych z językiem runtime." ... Oww ... To zabójca. – LightStriker

2
class Program 
{ 
    static void Main(string[] args) 
    { 
     var list = new Contacts(); 
     var a = new Contact() { Name = "a" }; 
     var b = new Contact() { Name = "b" }; 
     var c = new Contact() { Name = "c" }; 
     var d = new Contact() { Name = "d" }; 
     list.ContactList = new List<Contact>(); 
     list.ContactList.Add(a); 
     list.ContactList.Add(b); 
     list.ContactList.Add(c); 
     list.ContactList.Add(d); 

     foreach (var i in list) 
     { 
      Console.WriteLine(i.Name); 
     } 
    } 
} 

class Contacts : IEnumerable<Contact> 
{ 
    public List<Contact> ContactList { get; set; } 

    public IEnumerator<Contact> GetEnumerator() 
    { 
     return ContactList.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ContactList.GetEnumerator(); 
    } 
} 

class Contact 
{ 
    public string Name { get; set; } 
} 
0

Jak o właśnie rozszerzenie List<Contact>

Jeśli nie chcesz przedłużyć do innej grupy, jest to bardzo proste, szybka opcja:

class Contacts :List<Contact> 
{ 
} 
Powiązane problemy