przechodziłem przez IEnumerable i IEnumerator, ale nie mogłem uzyskać jednego punktu wyraźnie .. jeśli mamy foreach, to dlaczego potrzebujemy tych dwóch interfejsów? Czy jest jakikolwiek scenariusz, w którym musimy używać interfejsów. Jeśli tak, to ktoś może wyjaśnić na przykładzie. Wszelkie sugestie i uwagi są mile widziane. Dzięki. W wielu przypadkach interfejsówIEnumerable, IEnumerator vs foreach, kiedy używać tego, co
Odpowiedz
foreach
używa interfejsów. Potrzebujesz interfejsów, aby implementować sekwencję, którą następnie można użyć. (Bloki Iterator zazwyczaj bardzo ułatwiają to zadanie implementacyjne.)
Jednak, po prostu okazjonalnie może być przydatne użycie iteratorów bezpośrednio. Dobrym przykładem jest próba "powiązania" dwóch różnych sekwencji. Załóżmy na przykład, że otrzymujesz dwie sekwencje - jedną z nazw, jedną z przedziałów wiekowych i chcesz wydrukować te dwie razem. można napisać:
static void PrintNamesAndAges(IEnumerable<string> names, IEnumerable<int> ages)
{
using (IEnumerator<int> ageIterator = ages.GetEnumerator())
{
foreach (string name in names)
{
if (!ageIterator.MoveNext())
{
throw new ArgumentException("Not enough ages");
}
Console.WriteLine("{0} is {1} years old", name, ageIterator.Current);
}
if (ageIterator.MoveNext())
{
throw new ArgumentException("Not enough names");
}
}
}
Podobnie może być przydatna w użyciu iteracyjnej jeśli chcesz traktować (powiedzmy) pierwszy element odmiennie do reszty:
public T Max<T>(IEnumerable<T> items)
{
Comparer<T> comparer = Comparer<T>.Default;
using (IEnumerator<T> iterator = items.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("No elements");
}
T currentMax = iterator.Current;
// Now we've got an initial value, loop over the rest
while (iterator.MoveNext())
{
T candidate = iterator.Current;
if (comparer.Compare(candidate, currentMax) > 0)
{
currentMax = candidate;
}
}
return currentMax;
}
}
Teraz, jeśli "interesuje mnie różnica między IEnumerator<T>
i IEnumerable<T>
, możesz myśleć o niej w kategoriach baz danych: pomyśl o IEnumerable<T>
jako tabeli i IEnumerator<T>
jako kursorze. Możesz poprosić tabelę o nowy kursor, a jednocześnie możesz mieć wiele kursorów nad tym samym stołem.
Potrącenie tej różnicy może zająć trochę czasu, ale wystarczy pamiętać, że lista (lub tablica, lub cokolwiek innego) nie ma pojęcia "gdzie jesteś na liście", ale jest iteratorem na tej liście/array/niezależnie od tego, czy ma mieć ten stan jest pomocne.
Co Jon powiedział.
IEnumerable
lubIEnumerable<T>
: wdrażając ten obiekt stwierdza, że może dać Ci iterator, którego można użyć do przechodzenia przez sekwencję/kolekcji/setIEnumerator
lubIEnumerator<T>
: jeśli wywołanie metody GetEnumerator zdefiniowanego w poprzednim interfejsie otrzymujesz obiekt iteratora jako odniesienie do IEnumeratora. Umożliwia to wywołanie metody MoveNext() i pobranie bieżącego obiektu.foreach
: jest konstrukcją/fasadą C# w pewnym sensie, że nie musisz wiedzieć, jak działa pod maską. Wewnętrznie pobiera iterator i wywołuje odpowiednie metody, aby skoncentrować się na tym, co chcesz zrobić z każdym elementem (zawartością bloku foreach). W większości przypadków potrzebujesz foreach, chyba że implementujesz własny typ lub niestandardową iterację, w takim przypadku musisz poznać dwa pierwsze interfejsy.
Dzięki Gishu za uczynienie go bardziej zrozumiałym dla mnie. również uważam, że ten link jest bardzo użyteczny: http://stackoverflow.com/questions/558304/can-anyone-explain-ienumerable-and-ienumerator-to-me – Wondering
pamiętać, że nie mieć wdrożenia IEnumerator i ich varients używać foreach - IIRC, wszystko to musi to metoda GetEnumerator(), która zwraca obiekt, który ma metodę MoveNext() przekazujących a bool i właściwość Current zwracająca obiekt. Nie musisz używać IEnumeratora i IEnumerable, chociaż generalnie jest to bardzo dobry pomysł. Aby uzyskać więcej informacji, patrz here.
To dziwna, stara bestia, ta - możesz po prostu zastosuj dwie metody. Dużym problemem jest to, że system typów nie wie, że rzecz jest wymienna, więc wyobrażam sobie, że miałbyś problem z jej użyciem, na przykład, z Linq do Objects. –
Tak, to jest dziwne. Powodem, dla którego wspieramy tę funkcję jest to, że możesz napisać zbiór liczb całkowitych w C# 1.0 i wyliczyć je bez boksowania. Teraz, gdy mamy IE
@Eric Lippert: Jest jeszcze jedna zaleta tej cechy: pozwala uniknąć alokacji sterty dla enumeratorów strukturalnych, choć sugerowałbym, że klasy, których metody GetEnumerator zwrócą strukturę, powinny mieć metody IEnumerable.GetEnumerator, które zwracają klasy. – supercat
- 1. Jaki jest powód implementacji IEnumerable i IEnumerator
- 2. https vs ssl- kiedy używać co
- 3. Kiedy używać "tego" w Javie
- 4. Kiedy używać HtmlControls vs WebControls
- 5. Parallel.ForEach() vs. foreach (IEnumerable <T> .AsParallel()
- 6. Kiedy IEnumerable.GetEnumerator zostanie wywołany zamiast IEnumerable <T> .GetEnumerator?
- 7. Kiedy używać HttpMessageHandler vs ActionFilter?
- 8. Kiedy używać SQLITE_TRANSIENT vs SQLITE_STATIC?
- 9. Kiedy używać = domyślny vs = usuń
- 10. Kiedy używać approxfun vs. ok.
- 11. foreach vs ForEach przy użyciu plonu
- 12. Klasa C# to IEnumerable I IEnumerator w tym samym czasie. Jakie są tego problemy?
- 13. foreach na IEnumerable lub IList
- 14. IEnumerator Purpose
- 15. KIEDY używać serializacji vs zwykły POST
- 16. Kiedy należy używać `publishReplay` vs` shareReplay`?
- 17. Couchbase - Kiedy powinienem używać N1QL vs Widoki?
- 18. array_walk vs array_map vs foreach
- 19. Storm vs. Trident: Kiedy nie używać Trident?
- 20. IEnumerable paradox
- 21. Implementacja IEnumerable with Array
- 22. Kiedy używać Haystack/ElasticSearch vs ORM Django
- 23. Kiedy używać Cassandra vs Solr w DSE?
- 24. Kiedy należy używać Mockery vs JUnit4Mockery?
- 25. Linq All Vs Foreach
- 26. Kiedy odsłonić IEnumerable zamiast ICollection?
- 27. Kiedy używać hashtable
- 28. Async/Await VS Task.Run: Kiedy używać? Jak używać?
- 29. Zmienianie właściwości IEnumerator <T> .aktualnie
- 30. Kiedy powinieneś używać === vs ==,! == vs! =, Etc .. w javascript?
Dziękuję Jonowi za całą pomoc. Mam to teraz i będę uczyć się więcej, aby było jasne. Również znajduję następujący link bardzo użyteczny: http://stackoverflow.com/questions/558304/can-anyone-explain-ienumerable-and-ienumerator-to-me – Wondering
To jest przykład miejsca, w którym utknąłeś przy użyciu IEnumeratora aby pozostać wydajnym. http://stackoverflow.com/questions/1018407/what-jest-najwyklej-elegant-way-do-get-of-items-by-index-from--collection/1025137#1025137 –
@ Jon Skeet Bardzo podobał mi się sposób, w jaki zakodowałeś metodę Max. Mam jedno pytanie. użyłeś używając konstrukcji z IEnumberator. Wiem, że używanie utylizuje to, co się w nim znajduje(). Dlaczego użyłeś go na IEnumberator? –