Skip to content

Commit e0775e0

Browse files
committed
Update for the new extensions
Fixes #45758 Update the LINQ section to highlight C# 14 extension members over the C# 3 style `this` extension methods. In general, refer to "extension members" over "extension methods" when discussing the language feature. Use "extension methods" in the context of writing *methods* specifically, as in the query expression pattern.
1 parent 105cb8d commit e0775e0

File tree

5 files changed

+96
-91
lines changed

5 files changed

+96
-91
lines changed

docs/csharp/linq/get-started/features-that-support-linq.md

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
---
2-
title: "Language Features That Support LINQ"
2+
title: "Language features that support LINQ"
33
description: Learn about C# features to use with LINQ queries and in other contexts.
4-
ms.date: 04/22/2024
4+
ms.date: 12/01/2025
5+
ai-usage: ai-assisted
56
helpviewer_keywords:
67
- "LINQ [C#], features supporting LINQ"
78
---
8-
# C# Features That Support LINQ
9+
# C# features that support LINQ
910

10-
## Query Expressions
11+
## Query expressions
1112

12-
Query expressions use a declarative syntax similar to SQL or XQuery to query over <xref:System.Collections.Generic.IEnumerable%601?displayProperty=nameWithType> collections. At compile time, query syntax is converted to method calls to a LINQ provider's implementation of the standard query methods. Applications control the standard query operators that are in scope by specifying the appropriate namespace with a [`using`](../../language-reference/keywords/using-directive.md) directive. The following query expression takes an array of strings, groups them according to the first character in the string, and orders the groups.
13+
Query expressions use a declarative syntax similar to SQL or XQuery to query over <xref:System.Collections.Generic.IEnumerable%601?displayProperty=nameWithType> collections. At compile time, the compiler converts query syntax to method calls to a LINQ provider's implementation of the standard query methods. Applications control the standard query operators that are in scope by specifying the appropriate namespace with a [`using`](../../language-reference/keywords/using-directive.md) directive. The following query expression takes an array of strings, groups them according to the first character in the string, and orders the groups.
1314

1415
```csharp
1516
var query = from str in stringArray
@@ -18,7 +19,7 @@ var query = from str in stringArray
1819
select stringGroup;
1920
```
2021

21-
## Implicitly Typed Variables (var)
22+
## Implicitly typed variables (var)
2223

2324
You can use the [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) modifier to instruct the compiler to infer and assign the type, as shown here:
2425

@@ -30,25 +31,25 @@ var query = from str in stringArray
3031
select str;
3132
```
3233

33-
Variables declared as `var` are strongly typed, just like variables whose type you specify explicitly. The use of `var` makes it possible to create anonymous types, but only for local variables. For more information, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).
34+
Variables declared as `var` are strongly typed, just like variables whose type you specify explicitly. Using `var` makes it possible to create anonymous types, but only for local variables. For more information, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).
3435

35-
## Object and Collection Initializers
36+
## Object and collection initializers
3637

37-
Object and collection initializers make it possible to initialize objects without explicitly calling a constructor for the object. Initializers are typically used in query expressions when they project the source data into a new data type. Assuming a class named `Customer` with public `Name` and `Phone` properties, the object initializer can be used as in the following code:
38+
Object and collection initializers make it possible to initialize objects without explicitly calling a constructor for the object. You typically use initializers in query expressions when they project the source data into a new data type. Assuming a class named `Customer` with public `Name` and `Phone` properties, you can use the object initializer as in the following code:
3839

3940
```csharp
4041
var cust = new Customer { Name = "Mike", Phone = "555-1212" };
4142
```
4243

43-
Continuing with your `Customer` class, assume that there's a data source called `IncomingOrders`, and that for each order with a large `OrderSize`, you would like to create a new `Customer` based off of that order. A LINQ query can be executed on this data source and use object initialization to fill a collection:
44+
Continuing with your `Customer` class, assume that there's a data source called `IncomingOrders`, and that for each order with a large `OrderSize`, you want to create a new `Customer` based off of that order. You can execute a LINQ query on this data source and use object initialization to fill a collection:
4445

4546
```csharp
4647
var newLargeOrderCustomers = from o in IncomingOrders
4748
where o.OrderSize > 5
4849
select new Customer { Name = o.Name, Phone = o.Phone };
4950
```
5051

51-
The data source might have more properties defined than the `Customer` class such as `OrderSize`, but with object initialization, the data returned from the query is molded into the desired data type; you choose the data that is relevant to your class. As a result, you now have an <xref:System.Collections.Generic.IEnumerable%601?displayProperty=nameWithType> filled with the new `Customer`s you wanted. The preceding example can also be written in LINQ's method syntax:
52+
The data source might have more properties defined than the `Customer` class such as `OrderSize`, but with object initialization, the data returned from the query is molded into the desired data type; you choose the data that's relevant to your class. As a result, you now have an <xref:System.Collections.Generic.IEnumerable%601?displayProperty=nameWithType> filled with the new `Customer`s you wanted. You can also write the preceding example in LINQ's method syntax:
5253

5354
```csharp
5455
var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });
@@ -61,45 +62,46 @@ For more information, see:
6162
- [Object and Collection Initializers](../../programming-guide/classes-and-structs/object-and-collection-initializers.md)
6263
- [Query Expression Syntax for Standard Query Operators](../standard-query-operators/index.md)
6364

64-
## Anonymous Types
65+
## Anonymous types
6566

66-
The compiler constructs an [anonymous type](../../fundamentals/types/anonymous-types.md). The type name is only available to the compiler. Anonymous types provide a convenient way to group a set of properties temporarily in a query result without having to define a separate named type. Anonymous types are initialized with a new expression and an object initializer, as shown here:
67+
The compiler constructs an [anonymous type](../../fundamentals/types/anonymous-types.md). Only the compiler can access the type name. Anonymous types provide a convenient way to group a set of properties temporarily in a query result without having to define a separate named type. You initialize anonymous types with a new expression and an object initializer, as shown here:
6768

6869
```csharp
6970
select new {name = cust.Name, phone = cust.Phone};
7071
```
7172

7273
Beginning with C# 7, you can use [tuples](../../language-reference/builtin-types/value-tuples.md) to create unnamed types.
7374

74-
## Extension Methods
75+
## Extension members
7576

76-
An [extension method](../../programming-guide/classes-and-structs/extension-methods.md) is a static method that can be associated with a type, so that it can be called as if it were an instance method on the type. This feature enables you to, in effect, "add" new methods to existing types without actually modifying them. The standard query operators are a set of extension methods that provide LINQ query functionality for any type that implements <xref:System.Collections.Generic.IEnumerable%601>.
77+
An [extension member](../../programming-guide/classes-and-structs/extension-methods.md) is a static member of a static class associated with a type called the *receiver type*. You can call an extension member as if it were a member of the receiver type. This feature enables you to "add" new members to existing types without actually modifying them. The standard query operators are a set of extension methods that provide LINQ query functionality for any type that implements <xref:System.Collections.Generic.IEnumerable%601>.
7778

78-
## Lambda Expressions
79+
## Lambda expressions
7980

80-
A [lambda expressions](../../language-reference/operators/lambda-expressions.md) is an inline function that uses the `=>` operator to separate input parameters from the function body and can be converted at compile time to a delegate or an expression tree. In LINQ programming, you encounter lambda expressions when you make direct method calls to the standard query operators.
81+
A [lambda expression](../../language-reference/operators/lambda-expressions.md) is an inline function that uses the `=>` operator to separate input parameters from the function body and can be converted at compile time to a delegate or an expression tree. In LINQ programming, you encounter lambda expressions when you make direct method calls to the standard query operators.
8182

8283
## Expressions as data
8384

84-
Query objects are composable, meaning that you can return a query from a method. Objects that represent queries don't store the resulting collection, but rather the steps to produce the results when needed. The advantage of returning query objects from methods is that they can be further composed or modified. Therefore any return value or `out` parameter of a method that returns a query must also have that type. If a method materializes a query into a concrete <xref:System.Collections.Generic.List%601> or <xref:System.Array> type, it returns the query results instead of the query itself. A query variable that is returned from a method can still be composed or modified.
85+
Query objects are composable, meaning that you can return a query from a method. Objects that represent queries don't store the resulting collection, but rather the steps to produce the results when needed. The advantage of returning query objects from methods is that you can further compose or modify them. Therefore, any return value or `out` parameter of a method that returns a query must also have that type. If a method materializes a query into a concrete <xref:System.Collections.Generic.List%601> or <xref:System.Array> type, it returns the query results instead of the query itself. You can still compose or modify a query variable that's returned from a method.
8586

86-
In the following example, the first method `QueryMethod1` returns a query as a return value, and the second method `QueryMethod2` returns a query as an `out` parameter (`returnQ` in the example). In both cases, it's a query that is returned, not query results.
87+
In the following example, the first method `QueryMethod1` returns a query as a return value, and the second method `QueryMethod2` returns a query as an `out` parameter (`returnQ` in the example). In both cases, it's a query that's returned, not query results.
8788

8889
:::code language="csharp" source="./snippets/SnippetApp/ReturnQueryFromMethod.cs" id="return_query_from_method_1":::
8990

90-
Query `myQuery1` is executed in the following foreach loop.
91+
The following `foreach` loop executes query `myQuery1`.
9192

9293
:::code language="csharp" source="./snippets/SnippetApp/ReturnQueryFromMethod.cs" id="return_query_from_method_2":::
9394

9495
Rest the mouse pointer over `myQuery1` to see its type.
9596

96-
You also can execute the query returned from `QueryMethod1` directly, without using `myQuery1`.
97+
You can also execute the query returned from `QueryMethod1` directly, without using `myQuery1`.
9798

9899
:::code language="csharp" source="./snippets/SnippetApp/ReturnQueryFromMethod.cs" id="return_query_from_method_3":::
99100

100101
Rest the mouse pointer over the call to `QueryMethod1` to see its return type.
101102

102103
`QueryMethod2` returns a query as the value of its `out` parameter:
104+
103105
:::code language="csharp" source="./snippets/SnippetApp/ReturnQueryFromMethod.cs" id="return_query_from_method_4":::
104106

105107
You can modify a query by using query composition. In this case, the previous query object is used to create a new query object. This new object returns different results than the original query object.

0 commit comments

Comments
 (0)