Skip to content

Commit 25fae83

Browse files
authored
Merge pull request #49742 from wwlpublish/72e4a7ae727b8d605084f0ca780abb7d01b91fde2816067e61793aec2b5011df-live
Modules/M04-get-started-generic-anonymous-types
2 parents 957cea0 + 73c8766 commit 25fae83

16 files changed

+535
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.introduction
3+
title: Introduction
4+
metadata:
5+
title: Introduction
6+
description: "Introduction to the module."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 2
12+
content: |
13+
[!include[](includes/1-introduction.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.examine-generics
3+
title: Examine generics
4+
metadata:
5+
title: Examine generics
6+
description: "Learn how generics acts as code templates that allow you to define type-safe data structures without committing to an actual data type."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 6
12+
content: |
13+
[!include[](includes/2-examine-generics.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.explore-advanced-generics-concepts
3+
title: Explore advanced generics concepts
4+
metadata:
5+
title: Explore advanced generics concepts
6+
description: "Understand advanced concepts of generics, including covariance, contravariance, and generic constraints, to write more flexible, and reusable code."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 8
12+
content: |
13+
[!include[](includes/3-explore-advanced-generics-concepts.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.practical-applications-anonymous-types
3+
title: Practical applications of anonymous types
4+
metadata:
5+
title: Practical applications of anonymous types
6+
description: "Learn how to use anonymous types in C# for temporary data structures, LINQ queries, and efficient grouping of related data."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 7
12+
content: |
13+
[!include[](includes/4-practical-applications-anonymous-types.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.exercise-implement-generic-anonymous-types
3+
title: Exercise - Implement generic and anonymous types
4+
metadata:
5+
title: Exercise - Implement generic and anonymous types
6+
description: "Practice creating generics, advanced generics, and anonymous types in C# to write flexible, reusable, and efficient code."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 25
12+
content: |
13+
[!include[](includes/5-exercise-implement-generic-anonymous-types.md)]
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.knowledge-check
3+
title: Knowledge check
4+
metadata:
5+
title: Knowledge check
6+
description: "Check what you've learned in this module."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 3
12+
content: |
13+
[!include[](includes/6-knowledge-check.md)]
14+
quiz:
15+
title: "Check your knowledge"
16+
questions:
17+
- content: "What is the primary purpose of generics in programming?"
18+
choices:
19+
- content: "To allow code to handle multiple data types while ensuring type safety."
20+
isCorrect: true
21+
explanation: "Correct. Generics enables developers to write reusable code that works with different data types, ensuring type safety by catching errors at compile time."
22+
- content: "To improve runtime performance by optimizing memory usage."
23+
isCorrect: false
24+
explanation: "Incorrect. While generics can enhance performance by avoiding unnecessary type conversions, their primary purpose is to ensure type safety and code reusability."
25+
- content: "To simplify debugging by automatically generating error messages."
26+
isCorrect: false
27+
explanation: "Incorrect. Generics doesn't generate error messages for debugging; they ensure type safety during compilation, reducing runtime errors."
28+
- content: "Which of the following is an example of a generic class?"
29+
choices:
30+
- content: "`public class Box<T> { public T Item { get; set; } }`"
31+
isCorrect: true
32+
explanation: "Correct. This is a generic class where 'T' acts as a placeholder for the type, allowing the class to work with any data type."
33+
- content: "`public class Box { public int Item { get; set; } }`"
34+
isCorrect: false
35+
explanation: "Incorrect. This is a non-generic class because it's explicitly defined to work only with integers."
36+
- content: "`public class Box { public void AddItem(string item) { } }`"
37+
isCorrect: false
38+
explanation: "Incorrect. This is a non-generic class because it's designed to work only with strings, not multiple data types."
39+
- content: "Which of the following scenarios is a common use case for anonymous types in C#?"
40+
choices:
41+
- content: "Projecting selected properties in a Language-Integrated Query (LINQ)."
42+
isCorrect: true
43+
explanation: "Correct. Anonymous types are commonly used in LINQ queries to project results into objects with only the required properties."
44+
- content: "Defining a reusable class for multiple methods."
45+
isCorrect: false
46+
explanation: "Incorrect. Anonymous types aren't reusable and are intended for temporary use within a single method."
47+
- content: "Creating mutable objects for data manipulation."
48+
isCorrect: false
49+
explanation: "Incorrect. Anonymous types are immutable, meaning their properties are read-only and can't be modified after creation."
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-generic-anonymous-types.summary
3+
title: Summary
4+
metadata:
5+
title: Summary
6+
description: "Summarize the key concepts covered in this module."
7+
ms.date: 04/01/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 2
12+
content: |
13+
[!include[](includes/7-summary.md)]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Generics, advanced generics, and anonymous types in C# are powerful tools that help developers write flexible, reusable, and efficient code. Using generics enables improved performance while maintaining type safety.
2+
3+
Imagine you're managing a warehouse with various types of boxes. Each box contains different items, such as electronics, clothing, or fragile goods. To ensure everything is organized and handled efficiently, you need a system that can manage these diverse items safely and flexibly. You also want to sort and compare items across different categories without duplicating effort. Additionally, for quick summaries or reports, you need a way to group key details temporarily without creating detailed records for each item. By learning generics, advanced generics, and anonymous types in C#, you can create a system that is adaptable, efficient, and easy to maintain.
4+
5+
## Learning objectives
6+
7+
- Implement generic classes and methods to handle various data types efficiently.
8+
- Utilize advanced generics features like generic interfaces, covariance, contravariance, and generic math to address complex scenarios.
9+
- Apply anonymous types to create temporary, lightweight data structures for short-term use.
10+
- Explore use cases for anonymous types and tuples.
11+
12+
## Prerequisites
13+
14+
- Visual Studio Code installed with the C# Dev Kit.
15+
- Basic knowledge of the Visual Studio Code IDE.
16+
- Basic understanding of the C# programming language.
17+
- Familiar with classes, abstract classes, interfaces and inheritance.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
Imagine you have a box that can hold different items, like toys, books, or clothes. Instead of creating separate boxes for each type of item, you can use a single box with a label that specifies what it contains. Similar to how generics work in programming, they allow you to create a single class or method that can handle different types of data.
2+
3+
## Understand generics
4+
5+
Developers are enabled to define classes, methods, and interfaces with placeholders for data types by using generics. This placeholder behavior improves code reusability, ensures type safety by catching errors at compile time, and enhances performance by avoiding unnecessary type conversions.
6+
7+
- **Code reusability**: You can use the same code for different data types.
8+
9+
- **Type safety**: Errors related to incorrect data types are caught during compilation.
10+
11+
- **Performance**: Generics avoids unnecessary type conversions, making your code faster.
12+
13+
> [!NOTE]
14+
> Generics provides benefit when working with collections, such as lists or dictionaries, where the type of data stored can vary.
15+
16+
## How generics allow defining classes, methods, and interfaces with placeholders
17+
18+
Generics introduces type parameters, which act as placeholders for data types. For example, instead of creating a class that works only with integers, you can create a generic class that works with any type.
19+
20+
Here’s an example of a generic class:
21+
22+
```csharp
23+
public class Box<T>
24+
{
25+
public T Item { get; set; }
26+
27+
public void AddItem(T item)
28+
{
29+
Item = item;
30+
}
31+
}
32+
```
33+
34+
In this example:
35+
36+
- `T` is the type parameter.
37+
38+
- You can create instances of `Box<T>` for different types, like `Box<int>` or `Box<string>`.
39+
40+
When you use generics, the compiler replaces the type parameter with the actual type during compilation, ensuring type safety and avoiding runtime errors.
41+
42+
> [!TIP]
43+
> Think of `T` as a "placeholder" for the type you want to use. It makes your code flexible and reusable.
44+
45+
## Create generic classes and methods
46+
47+
Generic classes and methods are commonly used with collections, such as `List<T>` and `Dictionary<TKey, TValue>`. These collections provide type-safe ways to store and manipulate data.
48+
49+
Using a generic list example:
50+
51+
```csharp
52+
List<int> numbers = new List<int>();
53+
numbers.Add(1);
54+
numbers.Add(2);
55+
numbers.Add(3);
56+
57+
foreach (int number in numbers)
58+
{
59+
Console.WriteLine(number);
60+
}
61+
```
62+
63+
The generic list code demonstrates how to use a generic `List<int>` to store integers and iterate through them to print each number.
64+
65+
Creating a generic method example:
66+
67+
```csharp
68+
public T GetFirstItem<T>(List<T> items)
69+
{
70+
return items[0];
71+
}
72+
73+
List<string> names = new List<string> {"Hannah", "Mario"};
74+
string firstName = GetFirstItem(names);
75+
Console.WriteLine(firstName);
76+
```
77+
78+
This generic method retrieves the first item from a list of any type. For example, it gets the first name from a list of strings.
79+
80+
> [!TIP]
81+
> Use generics when you need to write reusable code that works with multiple data types while ensuring type safety.
82+
83+
Generics let you write flexible and reusable code using type parameters like `<T>`. They ensure type safety and simplify working with collections such as `List<T>` and `Dictionary<TKey, TValue>`. By learning generics, you can create adaptable and efficient code while avoiding common mistakes like forgetting to specify a type or using incompatible types.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
Imagine you have a warehouse with boxes that can hold different types of items. Some items, like fragile goods or oversized packages, need special handling. To manage the special case, you create rules to ensure everything is packed and processed efficiently.
2+
3+
Advanced generics in C# work similarly. Features like generic interfaces, covariance and contravariance, and generic math let you define flexible rules, ensure compatibility, and perform operations across data types, making your code reusable and efficient.
4+
5+
## Purpose and value of advanced generics
6+
7+
Advanced use of generics builds on the foundation of generics by introducing features that handle complex scenarios while maintaining type safety and efficiency.
8+
9+
- **Generic Interfaces**: Define type-safe contracts for implementing classes.
10+
11+
- **Covariance and Contravariance**: Enable flexible type assignments in method signatures and delegates.
12+
13+
- **Generic Math**: Perform mathematical operations generically across numeric types.
14+
15+
> [!TIP]
16+
> Use advanced generics to simplify complex scenarios while keeping your code reusable and type-safe.
17+
18+
## Generic interfaces
19+
20+
Generic interfaces are a key feature of advanced generics, allowing you to define type-safe contracts for implementing classes. They're especially useful when you want to enforce consistent behavior across different types while maintaining flexibility.
21+
22+
For example, the `IComparable<T>` interface allows objects to be compared by type:
23+
24+
```csharp
25+
public class Product : IComparable<Product>
26+
{
27+
public string Name { get; set; }
28+
public decimal Price { get; set; }
29+
30+
public int CompareTo(Product other)
31+
{
32+
return Price.CompareTo(other.Price);
33+
}
34+
}
35+
```
36+
37+
In this example:
38+
39+
- The `Product` class implements the `IComparable<Product>` interface.
40+
- The `CompareTo` method ensures that products can be compared based on their price.
41+
42+
Some commonly used generic interfaces in .NET include:
43+
44+
- **`IEnumerable<T>`**: Represents a collection of objects that can be enumerated.
45+
46+
- **`IComparer<T>`**: Defines a custom comparison for sorting objects.
47+
48+
- **`IEqualityComparer<T>`**: Defines custom equality logic for comparing objects.
49+
50+
Here’s an example of using `IComparer<T>` to sort a list of products:
51+
52+
```csharp
53+
public class ProductComparer : IComparer<Product>
54+
{
55+
public int Compare(Product x, Product y)
56+
{
57+
return x.Price.CompareTo(y.Price);
58+
}
59+
}
60+
61+
var products = new List<Product>
62+
{
63+
new Product { Name = "Laptop", Price = 1200 },
64+
new Product { Name = "Tablet", Price = 600 }
65+
};
66+
67+
products.Sort(new ProductComparer());
68+
```
69+
70+
- The `ProductComparer` class implements `IComparer<Product>` to sort products by price.
71+
- The `Sort` method uses the comparer to order the products.
72+
73+
> [!TIP]
74+
> Use generic interfaces to enforce type-safe behavior across different types while keeping your code flexible and reusable.
75+
76+
By using generic interfaces, you can enforce consistent behavior across different types while keeping your code flexible and reusable.
77+
78+
## Covariance and Contravariance
79+
80+
Covariance and contravariance allow flexibility when working with generic types, especially when assigning one type to another. They help ensure compatibility between related types in certain scenarios.
81+
82+
- **Covariance**: Allows you to assign a more specific type (derived type) to a more general type (base type).
83+
Think of it like storing a collection of apples (`IEnumerable<Apple>`) in a basket that can hold any fruit (`IEnumerable<Fruit>`).
84+
85+
- **Contravariance**: Allows you to assign a more general type (base type) to a more specific type (derived type).
86+
Think of it like using a handler for any fruit (`Action<Fruit>`) to process only apples (`Action<Apple>`).
87+
88+
Covariance allows you to assign a more specific type to a more general type. For example:
89+
90+
```csharp
91+
IEnumerable<string> strings = new List<string>();
92+
IEnumerable<object> objects = strings; // Covariance: string is a more specific type than object
93+
```
94+
95+
Contravariance allows you to assign a more general type to a more specific type. For example:
96+
97+
```csharp
98+
Action<object> handleObject = obj => Console.WriteLine(obj);
99+
Action<string> handleString = handleObject; // Contravariance: object is a more general type than string
100+
```
101+
102+
> [!TIP]
103+
> Covariance is useful when reading data, such as, iterating through a collection. Contravariance is useful when writing or processing data, such as passing parameters to a method.
104+
105+
## Generic math and methods
106+
107+
.NET 7 introduces generic math interfaces, enabling mathematical operations across numeric types.
108+
109+
The following example demonstrates a generic addition method:
110+
111+
```csharp
112+
static T Add<T>(T left, T right) where T : INumber<T>
113+
{
114+
return left + right;
115+
}
116+
117+
int result = Add(5, 10); // Works with integers
118+
double resultDouble = Add(5.5, 10.2); // Works with doubles
119+
```
120+
121+
- Generic math reduces redundant overloads and supports a wide range of numeric types.
122+
- It simplifies mathematical operations by allowing you to write reusable methods for numeric types.
123+
124+
> [!TIP]
125+
> Use generic math to write reusable methods for numeric operations, reducing the need for multiple overloads.
126+
127+
Advanced generics in C# build on the foundation of generics to handle more complex scenarios. Features like generic interfaces, covariance and contravariance, and generic math allow you to write flexible, reusable, and type-safe code. By learning these tools, you can simplify complex logic and create more adaptable applications.

0 commit comments

Comments
 (0)