Lambda vs Linq und warum eckige Klammern benutzen?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von ruediger_006.

    Lambda vs Linq und warum eckige Klammern benutzen?

    Ich habe folgendes Snippet gefunden und bräuchte hilfe dabei, es zu verstehen:

    Meine Fragen hierzu:

    Was macht [Select] in diesem Fall und warum ist es in eckige Klammern gesetzt? Ich weiss, dass man Select, wenn man es neu definiert (z.B. Function [Select] ... End Function) in eckige Klammern packen muss, weil es über Select Case belegt ist, aber in diesem Falle trifft doch eine Neudefinition nicht zu oder?

    Mir ist manchmal der unterschied zwischen Linq und mehrzeiligen Lambdas nicht so richtig klar, worum handelt es sich hier und kann mir vielleicht jemand eine Seite empfehlen, wo ich das vernünftig Lernen kann?

    VG

    Rüdi

    VB.NET-Quellcode

    1. 'Create WeeksInfo Object
    2. Dim jan1 = New DateTime(DateTime.Today.Year, 1, 1)
    3. 'beware different cultures, see other answers
    4. Dim startOfFirstWeek = jan1.AddDays(1 - CInt(jan1.DayOfWeek))
    5. Dim weeks = Enumerable.Range(0, 54).[Select](Function(i) New With { _
    6. Key .weekStart = startOfFirstWeek.AddDays(i * 7) _
    7. }).TakeWhile(Function(x) x.weekStart.Year <= jan1.Year).[Select](Function(x) New With { _
    8. x.weekStart, _
    9. Key .weekFinish = x.weekStart.AddDays(4) _
    10. }).SkipWhile(Function(x) x.weekFinish < jan1.AddDays(1)).[Select](Function(x, i) New With { _
    11. x.weekStart, _
    12. x.weekFinish, _
    13. Key .weekNum = i + 1 _
    14. })
    1) Dein Verständnis der eckigen Klammern ist richtig, und diese sind hier schlicht überflüssig.
    2) MS bezeichnet anonyme Methoden als Lambdas, einfach googeln: msdn.microsoft.com/de-de/library/bb531253.aspx:
    3) anonyme Methoden haben mit Linq eiglich nix zu tun, also schön, sind oft praktisch in Linq-Aufrufe einzubauen, aber Linq ist eine Sache des IEnumerable(Of T)-Interfaces in Kombination mit verschiedensten Delegaten (um genau und unverständlich zu sein ;) ).
    Was in deim Code ausschweifend genutzt ist, sind "einfach" diverse Extension-Methods, aussm Linq-Namespace. Lambda daran ist also nur die darin verbauten anonymen Methoden, wie

    VB.NET-Quellcode

    1. Function(x) New With { x.weekStart, Key .weekFinish = x.weekStart.AddDays(4) }

    4) Für viele Linq-Extensions(aber nicht für alle) gibts schmissige Spracherweiterungen, die hübscher aussehen (weniger Klammer-Verschachtelung), aber exakt dasselbe sind - nämlich Aufrufe der Linq-Extensions
    Mal ein Beispiel beider Schreibweisen

    VB.NET-Quellcode

    1. Dim di = New DirectoryInfo("..\..")
    2. Dim VbFileDates As IEnumerable(Of Date) = di.GetFiles().Where(Function(fi As FileInfo) fi.Extension = ".vb").Select(Function(fi) fi.LastAccessTime)
    3. Dim VbFileDatesInferred = di.GetFiles().Where(Function(fi) fi.Extension = ".vb").Select(Function(fi) fi.LastAccessTime)
    4. Dim VbFileDatesLinqExpr = From fi In di.GetFiles Where fi.Extension = ".vb" Select fi.LastAccessTime
    Konkret dein Beispiel konnte ich nicht hernehmen, weil zB für .TakeWhile() gibts keine Linq-Spracherweiterung.
    Beachte auch #3: dort wird nix deklariert, sondern der Compiler erkennt die sich ergebenden Datentypen selbst.
    #4 ist dann richtig bezeichnet eine "Linq-Abfrage" (im Gegensatz zu den vorigen Linq-Extension-Aufrufen), mit der ihr eigenen, gelegentlich praktischen Syntax: msdn.microsoft.com/de-de/library/bb384830(v=vs.100).aspx

    Ich glaub, der Begriff Lambda wird von den meisten falsch benutzt - "aonyme Methode" ist eindeutig eindeutiger.

    Edit: Ups! Es gibt ja doch einen Abfrage-Ausdruck für TakeWhile und SkipWhile - ja dann kann man dien Beispiel doch richtig umarbeiten, moment...
    Naja, ganz dasselbe ists nicht geworden, es gibt zwar TakeWhile und SkipWhile, aber fürs letzte Select-.[Select](Function(x, i) New With ... gibts nix.

    VB.NET-Quellcode

    1. Dim weeks2 = From i In Enumerable.Range(0, 54)
    2. Select weekstart = startOfFirstWeek.AddDays(i * 7)
    3. Take While weekstart.Year <= jan1.Year
    4. Select weekstart, weekFinish = weekstart.AddDays(4)
    5. Skip While weekFinish < jan1.AddDays(1)
    Hab den letzten Select einfach weggelassen, weil man kann die Query einfach in ein Array abfüllen, dann hat man ebensogute Indizees verfügbar.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()