Skip to content

Commit ea8ac64

Browse files
BillWagnerCopilot
andauthored
Update tutorials and program guide for modern extensions (#50132)
* Update sample for LINQ tutorial Update the sample code and snippet tags for the LINQ tutorial missed one edit. fix build * First pass edit * Second proofread * Finish edits in classes and structs * Finish programming guide. * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * respond to reviews. --------- Co-authored-by: Copilot <[email protected]>
1 parent f67b351 commit ea8ac64

File tree

17 files changed

+375
-415
lines changed

17 files changed

+375
-415
lines changed

docs/csharp/programming-guide/classes-and-structs/how-to-create-a-new-method-for-an-enumeration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "How to create a new method for an enumeration"
33
description: Learn how to use extension methods to add functionality to an enum in C#. This example shows an extension method called Passing for an enum called Grades.
4-
ms.date: 04/17/2025
4+
ms.date: 11/25/2025
55
helpviewer_keywords:
66
- "enumerations [C#]"
77
- "extension methods [C#], for enums"

docs/csharp/programming-guide/classes-and-structs/how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
---
22
title: "How to use implicitly typed local variables and arrays in a query expression"
33
description: Use implicitly typed local variables in C# to have the compiler determine the type of a local variable. You must use them to store anonymous types.
4-
ms.date: 07/20/2015
4+
ms.date: 11/25/2025
55
helpviewer_keywords:
66
- "implicitly-typed local variables [C#], how to use"
77
ms.topic: how-to
8-
ms.assetid: 6b7354d2-af79-427a-b6a8-f74eb8fd0b91
98
---
109
# How to use implicitly typed local variables and arrays in a query expression (C# Programming Guide)
1110

@@ -25,6 +24,6 @@ You can use implicitly typed local variables whenever you want the compiler to d
2524

2625
## See also
2726

28-
- [Extension Methods](./extension-methods.md)
27+
- [Extension members](./extension-methods.md)
2928
- [LINQ (Language-Integrated Query)](../../linq/index.md)
3029
- [LINQ in C#](../../linq/index.md)

docs/csharp/programming-guide/classes-and-structs/snippets/how-to-implement-and-call-a-custom-extension-method/Program.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using CustomExtensions;
1+
using CustomExtensions;
22

33
string s = "The quick brown fox jumped over the lazy dog.";
44
// Call the method as if it were an
@@ -13,12 +13,14 @@ namespace CustomExtensions
1313
// Extension methods must be defined in a static class.
1414
public static class StringExtension
1515
{
16-
// This is the extension method.
17-
// The first parameter takes the "this" modifier
18-
// and specifies the type for which the method is defined.
19-
public static int WordCount(this string str)
16+
extension(string str)
2017
{
21-
return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
18+
// This is the extension member.
19+
// The `str` parameter is declared on the extension declaration.
20+
public int WordCount()
21+
{
22+
return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
23+
}
2224
}
2325
}
2426
}

docs/csharp/programming-guide/classes-and-structs/snippets/how-to-implement-and-call-a-custom-extension-method/how-to-implement-and-call-a-custom-extension-method.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net9.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

docs/csharp/programming-guide/generics/constraints-on-type-parameters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Constraints on type parameters"
33
description: Learn about constraints on type parameters. Constraints tell the compiler what capabilities a type argument must have.
4-
ms.date: 10/10/2025
4+
ms.date: 11/25/2025
55
f1_keywords:
66
- "defaultconstraint_CSharpKeyword"
77
- "notnull_CSharpKeyword"

docs/csharp/programming-guide/generics/snippets/GenericWhereConstraints.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,20 +175,25 @@ unsafe public static byte[] ToByteArray<T>(this T argument) where T : unmanaged
175175
// </Snippet15>
176176

177177
// <Snippet16>
178-
public static TDelegate? TypeSafeCombine<TDelegate>(this TDelegate source, TDelegate target)
179-
where TDelegate : System.Delegate
180-
=> Delegate.Combine(source, target) as TDelegate;
178+
extension<TDelegate>(TDelegate source) where TDelegate : System.Delegate
179+
{
180+
public TDelegate? TypeSafeCombine(TDelegate target)
181+
=> Delegate.Combine(source, target) as TDelegate;
182+
}
181183
// </Snippet16>
182184

183185
// <Snippet18>
184-
public static Dictionary<int, string> EnumNamedValues<T>() where T : System.Enum
186+
extension<T>(T) where T : System.Enum
185187
{
186-
var result = new Dictionary<int, string>();
187-
var values = Enum.GetValues(typeof(T));
188+
public static Dictionary<int, string> EnumNamedValues()
189+
{
190+
var result = new Dictionary<int, string>();
191+
var values = Enum.GetValues(typeof(T));
188192

189-
foreach (int item in values)
190-
result.Add(item, Enum.GetName(typeof(T), item)!);
191-
return result;
193+
foreach (int item in values)
194+
result.Add(item, Enum.GetName(typeof(T), item)!);
195+
return result;
196+
}
192197
}
193198
// </Snippet18>
194199
}

docs/csharp/programming-guide/generics/snippets/generics.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<Nullable>enable</Nullable>
77
<ImplicitUsings>enable</ImplicitUsings>
88
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

docs/csharp/toc.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,6 @@ items:
558558
href: programming-guide/classes-and-structs/implicitly-typed-local-variables.md
559559
- name: "How to use implicitly typed local variables and arrays in a query expression"
560560
href: programming-guide/classes-and-structs/how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md
561-
- name: Extension Methods
562-
href: programming-guide/classes-and-structs/extension-methods.md
563561
- name: "How to implement and call a custom extension method"
564562
href: programming-guide/classes-and-structs/how-to-implement-and-call-a-custom-extension-method.md
565563
- name: "How to create a new method for an enumeration"
@@ -580,6 +578,8 @@ items:
580578
href: programming-guide/classes-and-structs/static-constructors.md
581579
- name: "How to write a copy constructor"
582580
href: programming-guide/classes-and-structs/how-to-write-a-copy-constructor.md
581+
- name: Extension members
582+
href: programming-guide/classes-and-structs/extension-methods.md
583583
- name: Finalizers
584584
href: programming-guide/classes-and-structs/finalizers.md
585585
- name: Object and Collection Initializers
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
namespace UnusedCode;
2+
3+
using LinqFaroShuffle;
4+
internal class InterimSteps
5+
{
6+
// <StepOne>
7+
static IEnumerable<string> Suits()
8+
{
9+
yield return "clubs";
10+
yield return "diamonds";
11+
yield return "hearts";
12+
yield return "spades";
13+
}
14+
15+
static IEnumerable<string> Ranks()
16+
{
17+
yield return "two";
18+
yield return "three";
19+
yield return "four";
20+
yield return "five";
21+
yield return "six";
22+
yield return "seven";
23+
yield return "eight";
24+
yield return "nine";
25+
yield return "ten";
26+
yield return "jack";
27+
yield return "queen";
28+
yield return "king";
29+
yield return "ace";
30+
}
31+
// </StepOne>
32+
33+
private static void InitialMain()
34+
{
35+
// <StepTwo>
36+
var startingDeck = from s in Suits()
37+
from r in Ranks()
38+
select (Suit: s, Rank: r);
39+
40+
// Display each card that's generated and placed in startingDeck
41+
foreach (var card in startingDeck)
42+
{
43+
Console.WriteLine(card);
44+
}
45+
// </StepTwo>
46+
47+
// <StepThree>
48+
var top = startingDeck.Take(26);
49+
var bottom = startingDeck.Skip(26);
50+
// </StepThree>
51+
52+
}
53+
54+
private void StartShuffling()
55+
{
56+
var startingDeck = from s in Suits()
57+
from r in Ranks()
58+
select (Suit: s, Rank: r);
59+
60+
// Display each card that's generated and placed in startingDeck
61+
foreach (var card in startingDeck)
62+
{
63+
Console.WriteLine(card);
64+
}
65+
66+
var top = startingDeck.Take(26);
67+
var bottom = startingDeck.Skip(26);
68+
69+
// <StepFive>
70+
var shuffledDeck = top.InterleaveSequenceWith(bottom);
71+
72+
foreach (var c in shuffledDeck)
73+
{
74+
Console.WriteLine(c);
75+
}
76+
// </StepFive>
77+
}
78+
79+
private void CompareSequences()
80+
{
81+
// <StepSix>
82+
var startingDeck = from s in Suits()
83+
from r in Ranks()
84+
select (Suit: s, Rank: r);
85+
86+
// Display each card generated and placed in startingDeck in the console
87+
foreach (var card in startingDeck)
88+
{
89+
Console.WriteLine(card);
90+
}
91+
92+
var top = startingDeck.Take(26);
93+
var bottom = startingDeck.Skip(26);
94+
95+
var shuffledDeck = top.InterleaveSequenceWith(bottom);
96+
97+
var times = 0;
98+
// Re-use the shuffle variable from earlier, or you can make a new one
99+
shuffledDeck = startingDeck;
100+
do
101+
{
102+
shuffledDeck = shuffledDeck.Take(26).InterleaveSequenceWith(shuffledDeck.Skip(26));
103+
104+
foreach (var card in shuffledDeck)
105+
{
106+
Console.WriteLine(card);
107+
}
108+
Console.WriteLine();
109+
times++;
110+
111+
} while (!startingDeck.SequenceEquals(shuffledDeck));
112+
113+
Console.WriteLine(times);
114+
// </StepSix>
115+
}
116+
117+
private void AddLogging()
118+
{
119+
// <StepSeven>
120+
var startingDeck = (from s in Suits().LogQuery("Suit Generation")
121+
from r in Ranks().LogQuery("Rank Generation")
122+
select (Suit: s, Rank: r)).LogQuery("Starting Deck");
123+
124+
foreach (var c in startingDeck)
125+
{
126+
Console.WriteLine(c);
127+
}
128+
129+
Console.WriteLine();
130+
var times = 0;
131+
var shuffle = startingDeck;
132+
133+
do
134+
{
135+
// Out shuffle
136+
/*
137+
shuffle = shuffle.Take(26)
138+
.LogQuery("Top Half")
139+
.InterleaveSequenceWith(shuffle.Skip(26)
140+
.LogQuery("Bottom Half"))
141+
.LogQuery("Shuffle");
142+
*/
143+
144+
// In shuffle
145+
shuffle = shuffle.Skip(26).LogQuery("Bottom Half")
146+
.InterleaveSequenceWith(shuffle.Take(26).LogQuery("Top Half"))
147+
.LogQuery("Shuffle");
148+
149+
foreach (var c in shuffle)
150+
{
151+
Console.WriteLine(c);
152+
}
153+
154+
times++;
155+
Console.WriteLine(times);
156+
} while (!startingDeck.SequenceEquals(shuffle));
157+
158+
Console.WriteLine(times);
159+
// </StepSeven>
160+
}
161+
}
162+
163+
// <StepFour>
164+
public static class CardExtensions
165+
{
166+
extension<T>(IEnumerable<T> sequence)
167+
{
168+
public IEnumerable<T> InterleaveSequenceWith(IEnumerable<T> second)
169+
{
170+
// Your implementation goes here
171+
return default;
172+
}
173+
}
174+
}
175+
// </StepFour>

samples/snippets/csharp/getting-started/console-linq/console-linq.csproj renamed to docs/csharp/tutorials/snippets/console-linq/LInqFaroShuffle.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<Nullable>enable</Nullable>
7+
<ImplicitUsings>enable</ImplicitUsings>
78
</PropertyGroup>
89

910
</Project>

0 commit comments

Comments
 (0)