LINQ. This stands for Language Integrated Query. In VB.NET we import the System.Linq namespace—this provides many extension methods, ones that act on collections.
LINQ allows queries. In a query expression, we describe a command in terms of the desired result. So we can say "get all items greater than 10" rather than use a loop.
A query. This example uses a query expression. The "result" Dim is assigned to a query's result: it uses a special syntax form. It examines all array elements, naming each "v."
Then The example uses the Where keyword to filter elements. It only accepts elements greater than or equal to 10.
So When we evaluate the "result" value in our For-Each loop, we see only the elements that the query selected. These are 10 and 100.
Imports System.Linq
Module Module1
Sub Main()
' An array of 4 elements.
Dim values() As Integer = {1, 10, 100, 5}
' Gets all values greater than 9.
Dim result = From v In values Where v >= 10
' Display all matching Integers.
For Each value As Integer In result
Console.WriteLine(value)
Next
End Sub
End Module10
100
Order By. With Order By we can sort the results of a query. This statement comes after other query clauses like "Where." By default it is Ascending, ordering from low to high.
Imports System.Linq
Module Module1
Sub Main()
Dim values() As Integer = {3, 10, -1, 30, -3}
' Order the elements from low to high (ascending).
Dim result = From v In values Order By v
For Each value As Integer In result
Console.WriteLine(value)
Next
End Sub
End Module-3
-1
3
10
30
Descending. We can apply the Descending keyword to an Order By clause in a query expression. This orders the elements from last to first (for strings, "Z" to "A").
Tip For numbers, Descending orders from largest to smallest. Strings use a reverse alphabetical sort.
Imports System.Linq
Module Module1
Sub Main()
Dim animals() As String = {"cat", "turtle", "ant"}
' Sort animals alphabetically, last to first.
Dim result = From a In animals
Order By a Descending
For Each value As String In result
Console.WriteLine(value)
Next
End Sub
End Moduleturtle
cat
ant
Group By, Into. With a query, we can also group elements together into automatically-generated groups. The syntax is confusing. We use the "Group" keyword twice—once for naming the group.
Next After By, we specify the property that will be used to separate groups (here I use Item1, part of the tuples).
And In the Into part of the Group clause, we assign an identifier to the group—it can be any valid identifier (I use "TupleGroup").
Result Each group contains a collection called TupleGroup (named in the program). We loop over it to display all values.
Module Module1
Sub Main()
' Create list of tuples with two items each.
Dim list = New List(Of Tuple(Of Integer, String))
list.Add(New Tuple(Of Integer, String)(5, "green"))
list.Add(New Tuple(Of Integer, String)(5, "blue"))
list.Add(New Tuple(Of Integer, String)(20, "orange"))
list.Add(New Tuple(Of Integer, String)(20, "yellow"))
list.Add(New Tuple(Of Integer, String)(20, "magenta"))
' Group tuples by their first item.' ... TupleGroup is an identifier name.
Dim result = From v In list
Group v By v.Item1 Into TupleGroup = Group
' Loop over each group and its items.
For Each value In result
Console.WriteLine(value.Item1)
For Each item In value.TupleGroup
Console.WriteLine(" " + item.Item2)
Next
Next
End Sub
End Module5
green
blue
20
orange
yellow
magenta
Extensions. The System.Linq namespace also gives us many extension methods. In VB.NET we do not need to import the System.Linq namespace to use these extensions.
Here We use Average to compute the average number in an array of 4 Integers. The average, a Double, happens to equal 5.
Module Module1
Sub Main()
Dim numbers() As Integer = {2, 4, 6, 8}
' Use the Average extension from System.Linq.
Dim average As Double = numbers.Average()
Console.WriteLine(average)
End Sub
End Module5
Chain extensions. Extension methods, like those found in LINQ, often return the results of their invocation. So we can call further extensions on them.
Here Take() returns the first three elements, in an IEnumerable collection. So Average() can be invoked on its result.
Module Module1
Sub Main()
Dim elements() As Integer = {5, 10, 15, 20, 25}
' Take first 3 numbers and average them.
Dim averageFirstThree = elements.Take(3).Average()
Console.WriteLine(averageFirstThree)
End Sub
End Module10
Any extension, lambda. The Any method returns True if the condition evaluates to True for any element in a sequence. This extension method can be used with a lambda expression.
Module Module1
Sub Main()
Dim values() As Integer = {10, -200, 1, 30, -1}
' See if the array has a negative number.
Dim hasNegative = values.Any(Function(x As Integer)
Return x < 0
End Function)
Console.WriteLine(hasNegative)
End Sub
End ModuleTrue
Query and extension call. We can combine query syntax with extension method calls. Consider this example—it orders the numbers with a query expression (Order By).
Then It uses the Take() extension upon the result of the query expression. This style is sometimes useful.
Imports System.Linq
Module Module1
Sub Main()
Dim numbers() As Integer = {5, 10, 1}
' Take first two numbers from ordered query.
Dim result = (From n In numbers
Order By n).Take(2)
For Each value As Integer In result
Console.WriteLine(value)
Next
End Sub
End Module1
5
FirstOrDefault. This is a useful LINQ extension method—it can help in many VB.NET programs. We call it on an IEnumerable instance. It has 2 possible results.
Part 1 If there is a first element in the collection (it has 1 or more elements), that value is returned by FirstOrDefault.
Part 2 If no first element exists (it has 0 elements total) the default value is returned. For int, this means we get a 0.
Module Module1
Sub Main()
Dim elements() As Integer = {5, 10, 15, 20, 25}
' Get first element safely.
Dim first1 = elements.FirstOrDefault()
Console.WriteLine("FIRSTORDEFAULT: {0}", first1)
elements = {}
' If no first element is present, we get the default value 0.
Dim first2 = elements.FirstOrDefault()
Console.WriteLine("FIRSTORDEFAULT: {0}", first2)
End Sub
End ModuleFIRSTORDEFAULT: 5
FIRSTORDEFAULT: 0
ElementAtOrDefault. Here we use the ElementAt and ElementAtOrDefault functions. Most developers will find ElementAtOrDefault to be the more useful form.
Info We call ElementAtOrDefault twice. If the index is in the range of the collection, it returns the string at that index.
And If the index if out-of-range, it returns the default value, which for a string is null (which is not displayed).
Detail This is the same as ElementAtOrDefault but will throw an exception if we pass an index that is not within the collection's size.
Module Module1
Sub Main()
Dim sizes = {"small", "medium", "large"}
' Use the safe ElementAtOrDefault function.
Dim element1 = sizes.ElementAtOrDefault(1)
Console.WriteLine("ELEMENTATORDEFAULT: {0}", element1)
Dim element100 = sizes.ElementAtOrDefault(100)
Console.WriteLine("ELEMENTATORDEFAULT: {0}", element100)
' Use ElementAt, which may throw an exception if out-of-range.
Dim element2 = sizes.ElementAt(2)
Console.WriteLine("ELEMENTAT: {0}", element2)
End Sub
End ModuleELEMENTATORDEFAULT: medium
ELEMENTATORDEFAULT:
ELEMENTAT: large
Summary. Many programs need no LINQ features: query expressions and extensions are not always useful. But these features have power. They make some programs shorter, easier to read.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on May 16, 2024 (edit link).