2016-02-09 12 views
5

Odczytywanie przez F# 4.0 spec, widziałem następujące na stronie 79 PDF:Dlaczego używałbyś Builder.Source() w niestandardowym narzędziu do tworzenia wyrażeń obliczeniowych?

Funkcja pomocnicza src(e) oznacza b.Source(e) jeśli najgłębsza ForEach jest z kodem użytkownika zamiast generowane przez tłumaczenia i budowniczym b zawiera metodę Source. W przeciwnym razie, src(e) oznacza .

Jest to w kontekście szczegółowego (bardzo szczegółowego) opisu specyfikacji, w jaki sposób przetwarzane są wyliczenia obliczeniowe i przekształcane w serie wywołań metod w obiekcie konstruktora wyrażenia. Scott Wlaschin's Computation Expressions series, który uważam za nieoceniony w pomaganiu mi w zrozumieniu pozostałych pojęć z wyrażeń obliczeniowych, nie wspomina o metodzie Source ani o żadnym innym odnośniku, jaki udało mi się znaleźć. (Google nie jest zbytnio pomocny w tej sprawie, ponieważ wiele osób mówi o kodzie źródłowym i wszelkie odniesienia do metod pochłaniania).

Nie widzę też Source udokumentowanej w dowolnym miejscu w MSDN page on computation expressions. QueryBuilder class używa Source, więc mam jeden przykład, na który mogę spojrzeć, ale nie ma wyjaśnienia, dlaczego byłoby to przydatne w innych okolicznościach.

W jakich okolicznościach chciałbyś mieć metodę Source na niestandardowym konstruktorze wyrażeń obliczeniowych? Jaki byłby scenariusz, w którym domyślna obsługa ForEach jest nieodpowiednia do swoich potrzeb i użyta byłaby metoda Source?

+0

@mydogisbox - Dzięki za link, ale widziałem tę stronę wcześniej. Zdaję sobie sprawę, że 'Source()' jest wywoływane z zawartością klauzuli 'in' (tzn.' Dla elementu na x' wywołuje wywołanie 'Source (x)'). Rozumiem, że 'Source' powinien zwrócić coś odpowiedniego do przekazania do' For'. Nie widzę jednak * dlaczego *. 'QueryBuilder.Source' wymaga albo IEnumerable albo IQueryable (który dziedziczy z IEnumerable), z których oba są odpowiednie dla funkcji' For' do iterowania. Dlaczego więc potrzebne jest wywołanie 'Source'? Dlaczego po prostu nie powiedzieć "Dali mi IEnumerable, więc I iterate to"? – rmunn

+0

Myślę, że mówimy o tym samym, po prostu nie miałem wystarczająco dużo miejsca w komentarzu, aby wyjaśnić, co mam na myśli. "For", o którym mówię, to 'QueryBuilder.For', który jest wywoływany do obsługi wyrażenia 'for' w zapytaniu {** dla ** klienta w db. Klienci wybierają klienta}. – rmunn

Odpowiedz

4

Nie mam żadnej poufnej wiedzy na ten temat, ale oto dlaczego myślę, że metoda istnieje, w oparciu o tłumaczenie i wdrożenie w wbudowanym QueryBuilder.

Wszystkie operacje w QueryBuilder stanowią źródło danych przy użyciu QuerySource<'R, 'Q> gdzie 'R jest typem elementów i 'Q jest rodzaj źródła danych - albo IEnumerable lub IQueryable.

Fakt, że istnieje tylko jeden typ danych oznacza, że ​​nie trzeba definiować odrębne przeciążeń dla IQueryable i IEnumerable - które w przeciwnym wypadku byłyby potrzebne, ponieważ metoda Run na końcu musi robić różne rzeczy dla IEnumerable i IQueryable.

Metoda Source umożliwia przekształcenie danych wejściowych, które zapytanie może przetwarzać w "wewnętrzną reprezentację" źródła danych. Na przeciwległym końcu metoda Run przekształca dane z tej wewnętrznej reprezentacji na zwykłą wartość. (W przypadku QueryBuilder, nigdy nie widzisz typu QuerySource w swoim kodzie.)

+0

"Tak więc, metoda' Source' pozwala na przekształcenie danych wejściowych, na które zapytanie może pracować, w jakąś "wewnętrzną reprezentację" źródła danych, a na odwrót, metoda "Run" zamienia dane z tej wewnętrznej reprezentacji na zwykłą wartość . " - To było zdanie, które sprawiło, że "kliknęło" dla mnie. Dzięki, to było wyjaśnienie, którego potrzebowałem. – rmunn

Powiązane problemy