• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Co robi ten kawałek kodu C# IEnumerable?

+1 głos
5,558 wizyt
pytanie zadane 2 kwietnia 2016 w C# przez winiardesign Gaduła (3,930 p.)

Od dwóch dnie walczę z kawałkami kodu, w których występuje interfejs IEnumerable i i IEnumerator.

Mam pytanie co robi ten kawałek kodu, bo albo jestem tak głupi albo nie mogę znaleźć odpowiedzi na google, która by mnie naprowadziła na rozwiązanie Product to klasa z produktami.

public class ShoppingCart : IEnumerable<Product>
    {
        public List<Product> Products { get; set; }

        public IEnumerator<Product> GetEnumerator()
        {
            return Products.GetEnumerator();
        }

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

 

3 odpowiedzi

0 głosów
odpowiedź 2 kwietnia 2016 przez achilles147 Dyskutant (9,580 p.)
wybrane 2 kwietnia 2016 przez winiardesign
 
Najlepsza
A widzisz to całkiem ciekawy kawałek kodu.

Na początek coś może o samym IEnumerable. Jest to interfejs który określa Ci, że masz jakiś ciąg elementów danego typu. Nie wiesz nic więcej o tym ciągu (jaka jest jego długość itp). Ten interfej ma tylko jedną metodę: GetEnumerator(), która zwraca Ci obiekt typu IEnumerator.

Jakby zajżeć do tego czym jest ten IEnumerator jest to kolejny interfejs, który ma właściwość Current oraz metode MoveNext().

A teraz wyjaśnienie : Każda kolekcja która implementure interfejs IEnumerable może wykonywać operacje na tzw Iteratorze (wzorzec projektowy -> metoda GetEnumerator()). Iterator pozwala poruszać się po kolekcji (iterować)  w jednym kierunki (metoda MoveNext() w interfejsie IEnumerator). I dzięki temu iteratorowi możesz np wywoływać pętlę foreach na tej kolekcji, która implementuje interfejs IEnumerable. Pętla foreach tak naprawdę nie robi nic innego niż wywołuje metodę MoveNext() (która zwraca boola przez co wiadomo czy przesunięcie się udało czy też nie, oraz zwraca Ci wartość elementu przez właściwość Current, która też znajduje się w interfejsie IEnumerator).

W twoim przypadku masz jakąś klasę, która implementuje interfejs IEnumerable<Product> (z tąd już wiesz, że będziesz mógł na niej wykonywać pętle foreach. Teraz zaglądając do środka klasy. IEnumerable wymaga implementacji metody GetEnumerator() i teraz wow masz aż dwie takie implementacje.

Implementacja IEnumerator<Product> GetEnumerator() : jak sam widzisz jest to opcja generyczna <Product> która mówi o tym że jak będziesz chciał iterować (np przez pętle foearch) po obiekcie typu ShoppingCart on sobie weźnie już zaimplementowany iterator z List<Product> bo lista ma już go zaimplementowany.

 

Implementacja IEnumerator IEnumerable.GetEnumerator() to jest wersja niegeneryczna. Raczej rzadko będziesz tego używać ale to się wykona wtedy kiedy stworzysz referencje typu niegenerycznego IEnumerable i przypiszesz do niej obiekt typu ShoppingCart. Ale ta implementacja jak widzisz zwraca Ci wynik metody GetEnumerator() czyli tej wersji górnej. Ostatecznie więc jakkolwiek się odniesiesz do obiektu typu ShoppingCart możesz po nim iterować i tak naprawdę będziesz iterować po twojej kolekcji List<Product> Products:)
0 głosów
odpowiedź 2 kwietnia 2016 przez drek Gaduła (4,980 p.)
Nic nie robi.

List<T> już implementuje interfejs IEnumerable<T> więc nie widzę potrzeby aby "wrapować" listę i implementować samemu ten interfejs.

Poczytaj sobie dokumentację

https://msdn.microsoft.com/en-us/library/9eekhta0(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx
komentarz 2 kwietnia 2016 przez winiardesign Gaduła (3,930 p.)
Czytałem dokumentacje i nie rozumiałem nadal tego kawałka kodu. Czyli równie dobrze mógłbym to usunąć i na to samo wyjdzie?
komentarz 2 kwietnia 2016 przez drek Gaduła (4,980 p.)
Ok. Inaczej.

Ten kod który zamieściłeś implementuje interfejs IEnumerable<T>. Poczytaj sobie poco i co o są interfejsy.

Ogólnie IEnumerable<T> jest abstrakcją kolekcji, (lub generatora potencjalnie nieskończonego - chociaż raczej tego raczej bardzo rzadko się używa), z którego można pobierać wartości (iterować) np. w pętli for. IEnumerable<T> nie jest modyfikowalne tj. niemożna usuwać lub bezpośrednio dodawać wartości do takiej kolekcji. Ponieważ z List<T> można pobierać wartości (iterować) to ta klasa również implementuje ten interfejs.

Ten kod, ok, implementuje interfejs IEnumerable<T>, ale nie wnosi nic poza tym, nie robi nic ciekawego, nie wnosi nic, nie tworzy wartości dodanej, dlatego napisałem, że nic nie robi, bo to co on robi to tylko wywoływanie tych samych metod z klasy List<T> - nic poza tym.

`ShoppingCart` ma być zbiorem produktów czyli koszykiem. Dlatego składa ona się z listy produktów. Produkty w koszyku można iterować dlatego implementuje interfejs IEnumerable<T>.
komentarz 2 kwietnia 2016 przez winiardesign Gaduła (3,930 p.)
No teraz czaję, dzięki wielkie.
0 głosów
odpowiedź 2 kwietnia 2016 przez winiardesign Gaduła (3,930 p.)
Dzięki za wyjaśnienie teraz zrozumiałem o co chodzi w tym IEnumerable<T>  i IEnumerator<T>

Podobne pytania

0 głosów
1 odpowiedź 761 wizyt
pytanie zadane 28 kwietnia 2017 w C# przez Alex.Ironside Stary wyjadacz (14,920 p.)
0 głosów
1 odpowiedź 226 wizyt
–2 głosów
0 odpowiedzi 225 wizyt

93,424 zapytań

142,422 odpowiedzi

322,646 komentarzy

62,785 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...