2010-10-08 9 views
7

Zdaję sobie sprawę, że jest to częściowo subiektywne, ale ogólnie jestem ciekawy opinii społeczności i nie udało mi się znaleźć istniejącego problemu, który rozwiązuje ten problem.Kiedy lambda w metodzie rozszerzenia robi zbyt wiele?

Jestem w nieco religijnej debacie z innym współpracownikiem o konkretnej instrukcji Select w zapytaniu L2EF.

.Select(r => 
{ 
    r.foo.Bar = r.bar; 
    r.foo.Bar.BarType = r.Alpha; 
    if (r.barAddress != null) 
    { 
     r.foo.Bar.Address = r.barAddress; 
     r.foo.Bar.Address.State = r.BarState; 
    } 
    if (r.baz != null) 
    { 
     r.foo.Bar.Baz = r.baz; 
     if (r.bazAddress != null) 
     { 
      r.foo.Bar.Baz.Address = r.bazAddress; 
      r.foo.Bar.Baz.Address.State = r.BazState; 
     } 
    } 
    return r.foo; 
}) 

Ostrzeżenia:

  • Jest Linq-Podmiotów
  • To po praca w DB jak zostały wykonane i powrócił
  • Parametr wejściowy r jest anonimowa

Osobiście jestem zdania, że w (a) klauzula wyboru nie powinna zmieniać wartości, powinna jedynie projektować. Jego argumentem jest to, że niczego nie zmienia, po prostu upewnia się, że wszystko zostało poprawnie zainicjowane w wyniku zapytania DB. Po drugie, myślę, że gdy zaczyna on przechodzić do pełnych bloków kodu i instrukcji zwrotnych, nadszedł czas, aby zdefiniować metodę lub nawet Func<T, U> i nie robić tego wszystkiego w linii. Tutaj komplikatorem jest, że dane wejściowe są anonimowe, więc trzeba zdefiniować typ. Niemniej jednak wciąż debatujemy nad punktem ogólnym, jeśli nie konkretnym.

Kiedy więc wyrażenie lambda robi zbyt wiele? Gdzie narysujesz rozmytą linię w piasku?

+0

Wydaje się, że złożoność kodu wynika ze złożoności anonimowego typu; czy taki złożony anonimowy typ jest naprawdę potrzebny? –

+0

@Dan, rzeczywiste zapytanie dotyczy lewych złączeń przechodzących przez 8 różnych jednostek, przy czym typ anonimowy zawiera po prostu obiekty tych elementów. nie jest to złożony typ anonimowy, per se, jest po prostu nieokreślony. to jest jak 'select new {foo, bar, baz,/* itd. * /}' –

+0

To jest oczywiście Select z efektami ubocznymi. Zupełnie nie w zamyśle. W tym celu istnieje "foreach();". – Dykam

Odpowiedz

2

Moim pierwszym instynktem jest zgodzić się z tobą, przede wszystkim w kwestii wielkości i złożoności.

Jest on jednak używany w kontekście, w którym będzie (lub czasami będzie) wykonywany jako coś innego niż kod .NET (szczególnie jeśli zostanie zamieniony na część zapytania SQL), stanę się o wiele bardziej tolerancyjny wobec tego.

Tak, to gdzie mogę narysować linię rozmytej, a także dlaczego poruszam go ponownie :)

1

Zgadzam się również z select() należy stosować do projekcji. Wolałbym raczej użyć słowa kluczowego "let" do sprawdzenia z wyprzedzeniem, aby ta projekcja w Select() mogła pozostać czysta. Umożliwi to Select() odnieść się do zestawu zmiennych za pomocą "let".

1

Nie sądzę, że to długa ekspresja lambda, osobiście. Myślę, że w przyszłości zobaczysz dużo bardziej złożone i zagnieżdżone lambdy. Zwłaszcza z czymś takim jak Rx.

Jeśli chodzi o zmiany stanu ... cóż, tutaj właśnie inicjuje wartości. Byłbym zaniepokojony, gdyby to był przypisanie stanu jakiejś zmiennej spoza lambda, ale to wszystko inicjalizacja r, więc wydaje mi się to w porządku.

1

Musiałem patrzeć na to przez chwilę, zanim zobaczyłem, co mnie dręczy.

  1. To wymaga refaktoryzacji.

  2. Fakt, że zajęło mi to dużo czasu, aby przeczytać intencję lambda.

Nie jestem pewien, czy mogę wziąć stronę na temat definicji pracy Select, ale zgadzam się, że im krócej będziesz w stanie utrzymać lambdę, tym lepiej. Podziel go na ponowne użycie, jeśli inicjalizacja po pobraniu dB jest tak potrzebna.

0

Musisz wziąć pod uwagę inne alternatywy ... czy jest lepsze miejsce na umieszczenie tej logiki. Tak czy inaczej, przechodzisz przez każdą jednostkę w LINQ lub w pętli foreach, aby wykonać tę dodatkową pracę ... Chyba że chcesz ją przekształcić we własną metodę rozszerzenia, powiedziałbym, że jeśli to działa.

Wizualnie, to nie jest takie brudne, więc to plus. Możesz też sprawdzić, czy słowo kluczowe let (w zasadzie podkwerenda) kupuje cokolwiek innego.

0

Długość lambda nie przeszkadza mi wcale. Ale zgodziłbym się z uczuciem brudu, gdy przypisujesz wartość w swoim oświadczeniu wyboru. Czynniki inicjalizacyjne uwzględniam w instrukcji tuż poniżej instrukcji select.

Powiązane problemy